diff --git a/android/app/build.gradle b/android/app/build.gradle
index 31d08c4ef5ca8..4340d05cf596a 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -243,5 +243,10 @@ task copyDownloadableDepsToLibs(type: Copy) {
}
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
-apply plugin: 'com.google.gms.google-services'
+def googleServicesFile = rootProject.file('app/google-services.json')
+if (googleServicesFile.exists()) {
+ apply plugin: 'com.google.gms.google-services' // Google Play services Gradle plugin
+}
apply plugin: 'com.google.firebase.crashlytics'
+
+
diff --git a/android/app/src/main/assets/airshipconfig.properties b/android/app/src/main/assets/airshipconfig.properties
new file mode 100644
index 0000000000000..6e37dfb7465e9
--- /dev/null
+++ b/android/app/src/main/assets/airshipconfig.properties
@@ -0,0 +1,9 @@
+developmentAppKey = uulSSfTDQJ2r0PMpjRrhmQ
+developmentAppSecret = D4Bhf0HrQEehrPua74Tyiw
+
+productionAppKey = 55vypj0ARc6cN09MX7ogtQ
+productionAppSecret = EsSaqbdLSvmyC6kSBFJCtQ
+
+# Notification Customization
+notificationIcon = ic_notification
+notificationAccentColor = #2EAAE2
diff --git a/android/app/src/main/res/drawable-hdpi/ic_notification.png b/android/app/src/main/res/drawable-hdpi/ic_notification.png
new file mode 100644
index 0000000000000..e084753fb90ed
Binary files /dev/null and b/android/app/src/main/res/drawable-hdpi/ic_notification.png differ
diff --git a/android/app/src/main/res/drawable-mdpi/ic_notification.png b/android/app/src/main/res/drawable-mdpi/ic_notification.png
new file mode 100644
index 0000000000000..669579148c619
Binary files /dev/null and b/android/app/src/main/res/drawable-mdpi/ic_notification.png differ
diff --git a/android/app/src/main/res/drawable-xhdpi/ic_notification.png b/android/app/src/main/res/drawable-xhdpi/ic_notification.png
new file mode 100644
index 0000000000000..18c06a8d16c3b
Binary files /dev/null and b/android/app/src/main/res/drawable-xhdpi/ic_notification.png differ
diff --git a/android/app/src/main/res/drawable-xxhdpi/ic_notification.png b/android/app/src/main/res/drawable-xxhdpi/ic_notification.png
new file mode 100644
index 0000000000000..da94014c33f09
Binary files /dev/null and b/android/app/src/main/res/drawable-xxhdpi/ic_notification.png differ
diff --git a/android/app/src/main/res/drawable-xxxhdpi/ic_notification.png b/android/app/src/main/res/drawable-xxxhdpi/ic_notification.png
new file mode 100644
index 0000000000000..96f1cb18a2be8
Binary files /dev/null and b/android/app/src/main/res/drawable-xxxhdpi/ic_notification.png differ
diff --git a/ios/AirshipConfig.plist b/ios/AirshipConfig.plist
new file mode 100644
index 0000000000000..3502dc33584f5
--- /dev/null
+++ b/ios/AirshipConfig.plist
@@ -0,0 +1,16 @@
+
+
+
+
+ detectProvisioningMode
+
+ developmentAppKey
+ uulSSfTDQJ2r0PMpjRrhmQ
+ developmentAppSecret
+ D4Bhf0HrQEehrPua74Tyiw
+ productionAppKey
+ 55vypj0ARc6cN09MX7ogtQ
+ productionAppSecret
+ EsSaqbdLSvmyC6kSBFJCtQ
+
+
diff --git a/ios/Podfile b/ios/Podfile
index 0bc36d16e8c67..175f3f2cbc656 100644
--- a/ios/Podfile
+++ b/ios/Podfile
@@ -1,7 +1,7 @@
require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
-platform :ios, '10.0'
+platform :ios, '11.0'
target 'ReactNativeChat' do
config = use_native_modules!
diff --git a/ios/Podfile.lock b/ios/Podfile.lock
index 01144dc11cf22..6a5fc0c690fc1 100644
--- a/ios/Podfile.lock
+++ b/ios/Podfile.lock
@@ -1,4 +1,16 @@
PODS:
+ - Airship (13.5.4):
+ - Airship/Automation (= 13.5.4)
+ - Airship/Core (= 13.5.4)
+ - Airship/ExtendedActions (= 13.5.4)
+ - Airship/MessageCenter (= 13.5.4)
+ - Airship/Automation (13.5.4):
+ - Airship/Core
+ - Airship/Core (13.5.4)
+ - Airship/ExtendedActions (13.5.4):
+ - Airship/Core
+ - Airship/MessageCenter (13.5.4):
+ - Airship/Core
- boost-for-react-native (1.63.0)
- CocoaAsyncSocket (7.6.4)
- CocoaLibEvent (1.0.0)
@@ -141,7 +153,7 @@ PODS:
- OpenSSL-Universal (1.0.2.19):
- OpenSSL-Universal/Static (= 1.0.2.19)
- OpenSSL-Universal/Static (1.0.2.19)
- - PromisesObjC (1.2.11)
+ - PromisesObjC (1.2.10)
- RCTRequired (0.63.3)
- RCTTypeSafety (0.63.3):
- FBLazyVector (= 0.63.3)
@@ -395,6 +407,9 @@ PODS:
- Firebase/Crashlytics (~> 6.30.0)
- React-Core
- RNFBApp
+ - urbanairship-react-native (8.1.0):
+ - Airship (= 13.5.4)
+ - React
- Yoga (1.14.0)
- YogaKit (1.18.1):
- Yoga (~> 1.14)
@@ -456,10 +471,12 @@ DEPENDENCIES:
- "RNFBAnalytics (from `../node_modules/@react-native-firebase/analytics`)"
- "RNFBApp (from `../node_modules/@react-native-firebase/app`)"
- "RNFBCrashlytics (from `../node_modules/@react-native-firebase/crashlytics`)"
+ - urbanairship-react-native (from `../node_modules/urbanairship-react-native`)
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
SPEC REPOS:
trunk:
+ - Airship
- boost-for-react-native
- CocoaAsyncSocket
- CocoaLibEvent
@@ -555,10 +572,13 @@ EXTERNAL SOURCES:
:path: "../node_modules/@react-native-firebase/app"
RNFBCrashlytics:
:path: "../node_modules/@react-native-firebase/crashlytics"
+ urbanairship-react-native:
+ :path: "../node_modules/urbanairship-react-native"
Yoga:
:path: "../node_modules/react-native/ReactCommon/yoga"
SPEC CHECKSUMS:
+ Airship: cbbd372a4ffc8dcfeacec01fd623155ec41f33ed
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
CocoaAsyncSocket: 694058e7c0ed05a9e217d1b3c7ded962f4180845
CocoaLibEvent: 2fab71b8bd46dd33ddb959f7928ec5909f838e3f
@@ -585,7 +605,7 @@ SPEC CHECKSUMS:
GoogleUtilities: 7f2f5a07f888cdb145101d6042bc4422f57e70b3
nanopb: c43f40fadfe79e8b8db116583945847910cbabc9
OpenSSL-Universal: 8b48cc0d10c1b2923617dfe5c178aa9ed2689355
- PromisesObjC: 8c196f5a328c2cba3e74624585467a557dcb482f
+ PromisesObjC: b14b1c6b68e306650688599de8a45e49fae81151
RCTRequired: 48884c74035a0b5b76dbb7a998bd93bcfc5f2047
RCTTypeSafety: edf4b618033c2f1c5b7bc3d90d8e085ed95ba2ab
React: f36e90f3ceb976546e97df3403e37d226f79d0e3
@@ -616,9 +636,10 @@ SPEC CHECKSUMS:
RNFBAnalytics: 6fe130045b06fb4173d6f44058894007bb30b9a2
RNFBApp: 570b136767f588b7eef0ab918284e9fe364d0c3e
RNFBCrashlytics: 7b60463c742f830255fa76f13a837f95c6581700
+ urbanairship-react-native: fa123940041a6a13ab7dac192e32833c53754f00
Yoga: 7d13633d129fd179e01b8953d38d47be90db185a
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
-PODFILE CHECKSUM: 7f6bb9c130ea13236f8249f800f75d671c1833fa
+PODFILE CHECKSUM: d03a22d8299d9564ca7fc55d0a779f6fbf0d2b37
COCOAPODS: 1.9.3
diff --git a/ios/ReactNativeChat.xcodeproj/project.pbxproj b/ios/ReactNativeChat.xcodeproj/project.pbxproj
index 710ee40632db8..0fa565e0bfc75 100644
--- a/ios/ReactNativeChat.xcodeproj/project.pbxproj
+++ b/ios/ReactNativeChat.xcodeproj/project.pbxproj
@@ -9,6 +9,7 @@
/* Begin PBXBuildFile section */
00E356F31AD99517003FC87E /* ReactNativeChatTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* ReactNativeChatTests.m */; };
0F5BE0CE252686330097D869 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 0F5BE0CD252686320097D869 /* GoogleService-Info.plist */; };
+ 11973047871545DDB8E5B212 /* libPods-ReactNativeChat-ReactNativeChatTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC449A52E4E55FAE6F278AE2 /* libPods-ReactNativeChat-ReactNativeChatTests.a */; };
12DD1878FCB9487C9F031C86 /* GTAmericaExpMono-Rg.otf in Resources */ = {isa = PBXBuildFile; fileRef = 8437A5A38F2047E0BCCD7C2F /* GTAmericaExpMono-Rg.otf */; };
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
@@ -20,10 +21,10 @@
1E76D5252522316A005A268F /* GTAmericaExp-Thin.otf in Resources */ = {isa = PBXBuildFile; fileRef = A292718541C841859D97DF2F /* GTAmericaExp-Thin.otf */; };
425866037F4C482AAB46CB8B /* GTAmericaExp-BdIt.otf in Resources */ = {isa = PBXBuildFile; fileRef = A8D6F2F722FD4E66A38EBBB6 /* GTAmericaExp-BdIt.otf */; };
6856B78873B64C44A92E51DB /* GTAmericaExp-MdIt.otf in Resources */ = {isa = PBXBuildFile; fileRef = DB5A1365442D4419AF6F08E5 /* GTAmericaExp-MdIt.otf */; };
- 712B637C71EDACB60BFCCFDF /* libPods-ReactNativeChat-ReactNativeChatTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5198B14DF64811534104106B /* libPods-ReactNativeChat-ReactNativeChatTests.a */; };
- 7EF88515CE8703E46E771C2D /* libPods-ReactNativeChat.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B2E64A28C6D8EC058C5C3144 /* libPods-ReactNativeChat.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 */; };
+ A53739628A74DEA3CA282B7A /* libPods-ReactNativeChat.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DFA0FAB15AD0FB875AD1C944 /* libPods-ReactNativeChat.a */; };
+ E9DF872D2525201700607FDC /* AirshipConfig.plist in Resources */ = {isa = PBXBuildFile; fileRef = E9DF872C2525201700607FDC /* AirshipConfig.plist */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -48,10 +49,8 @@
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = ReactNativeChat/Images.xcassets; sourceTree = ""; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = ReactNativeChat/Info.plist; sourceTree = ""; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = ReactNativeChat/main.m; sourceTree = ""; };
- 2061509B833DB0123E4416F5 /* Pods-ReactNativeChat.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeChat.release.xcconfig"; path = "Target Support Files/Pods-ReactNativeChat/Pods-ReactNativeChat.release.xcconfig"; sourceTree = ""; };
- 499D0486251AC7F1000B666B /* Chat.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = Chat.entitlements; path = ReactNativeChat/Chat.entitlements; sourceTree = ""; };
- 5198B14DF64811534104106B /* libPods-ReactNativeChat-ReactNativeChatTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ReactNativeChat-ReactNativeChatTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
- 66FC9F8F0AF1190BE595FC04 /* Pods-ReactNativeChat.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeChat.debug.xcconfig"; path = "Target Support Files/Pods-ReactNativeChat/Pods-ReactNativeChat.debug.xcconfig"; sourceTree = ""; };
+ 2656E49219DD99C2A26000B3 /* Pods-ReactNativeChat-ReactNativeChatTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeChat-ReactNativeChatTests.debug.xcconfig"; path = "Target Support Files/Pods-ReactNativeChat-ReactNativeChatTests/Pods-ReactNativeChat-ReactNativeChatTests.debug.xcconfig"; sourceTree = ""; };
+ 3836C07D427AF7E81680B81E /* Pods-ReactNativeChat.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeChat.debug.xcconfig"; path = "Target Support Files/Pods-ReactNativeChat/Pods-ReactNativeChat.debug.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 = ""; };
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = ReactNativeChat/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 = ""; };
@@ -59,12 +58,14 @@
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 = ""; };
+ A64B7A5E2FB2ADF3F0DB4820 /* Pods-ReactNativeChat.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeChat.release.xcconfig"; path = "Target Support Files/Pods-ReactNativeChat/Pods-ReactNativeChat.release.xcconfig"; 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 = ""; };
- B2E64A28C6D8EC058C5C3144 /* libPods-ReactNativeChat.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ReactNativeChat.a"; sourceTree = BUILT_PRODUCTS_DIR; };
- B81A8F09B6065AF7D0A5D2CD /* Pods-ReactNativeChat-ReactNativeChatTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeChat-ReactNativeChatTests.release.xcconfig"; path = "Target Support Files/Pods-ReactNativeChat-ReactNativeChatTests/Pods-ReactNativeChat-ReactNativeChatTests.release.xcconfig"; sourceTree = ""; };
- BB3B578785B6B7D4E739A8C8 /* Pods-ReactNativeChat-ReactNativeChatTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeChat-ReactNativeChatTests.debug.xcconfig"; path = "Target Support Files/Pods-ReactNativeChat-ReactNativeChatTests/Pods-ReactNativeChat-ReactNativeChatTests.debug.xcconfig"; sourceTree = ""; };
+ C0FF5FF7940AEF7E12B34F6D /* Pods-ReactNativeChat-ReactNativeChatTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ReactNativeChat-ReactNativeChatTests.release.xcconfig"; path = "Target Support Files/Pods-ReactNativeChat-ReactNativeChatTests/Pods-ReactNativeChat-ReactNativeChatTests.release.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 = ""; };
+ DC449A52E4E55FAE6F278AE2 /* libPods-ReactNativeChat-ReactNativeChatTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ReactNativeChat-ReactNativeChatTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+ DFA0FAB15AD0FB875AD1C944 /* libPods-ReactNativeChat.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ReactNativeChat.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 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; };
/* End PBXFileReference section */
@@ -74,7 +75,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 712B637C71EDACB60BFCCFDF /* libPods-ReactNativeChat-ReactNativeChatTests.a in Frameworks */,
+ 11973047871545DDB8E5B212 /* libPods-ReactNativeChat-ReactNativeChatTests.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -82,7 +83,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 7EF88515CE8703E46E771C2D /* libPods-ReactNativeChat.a in Frameworks */,
+ A53739628A74DEA3CA282B7A /* libPods-ReactNativeChat.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -110,7 +111,7 @@
isa = PBXGroup;
children = (
0F5BE0CD252686320097D869 /* GoogleService-Info.plist */,
- 499D0486251AC7F1000B666B /* Chat.entitlements */,
+ E9DF872C2525201700607FDC /* AirshipConfig.plist */,
008F07F21AC5B25A0029DE68 /* main.jsbundle */,
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
13B07FB01A68108700A75B9A /* AppDelegate.m */,
@@ -127,8 +128,8 @@
children = (
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
ED2971642150620600B7C4FE /* JavaScriptCore.framework */,
- B2E64A28C6D8EC058C5C3144 /* libPods-ReactNativeChat.a */,
- 5198B14DF64811534104106B /* libPods-ReactNativeChat-ReactNativeChatTests.a */,
+ DFA0FAB15AD0FB875AD1C944 /* libPods-ReactNativeChat.a */,
+ DC449A52E4E55FAE6F278AE2 /* libPods-ReactNativeChat-ReactNativeChatTests.a */,
);
name = Frameworks;
sourceTree = "";
@@ -184,10 +185,10 @@
EC29677F0A49C2946A495A33 /* Pods */ = {
isa = PBXGroup;
children = (
- 66FC9F8F0AF1190BE595FC04 /* Pods-ReactNativeChat.debug.xcconfig */,
- 2061509B833DB0123E4416F5 /* Pods-ReactNativeChat.release.xcconfig */,
- BB3B578785B6B7D4E739A8C8 /* Pods-ReactNativeChat-ReactNativeChatTests.debug.xcconfig */,
- B81A8F09B6065AF7D0A5D2CD /* Pods-ReactNativeChat-ReactNativeChatTests.release.xcconfig */,
+ 3836C07D427AF7E81680B81E /* Pods-ReactNativeChat.debug.xcconfig */,
+ A64B7A5E2FB2ADF3F0DB4820 /* Pods-ReactNativeChat.release.xcconfig */,
+ 2656E49219DD99C2A26000B3 /* Pods-ReactNativeChat-ReactNativeChatTests.debug.xcconfig */,
+ C0FF5FF7940AEF7E12B34F6D /* Pods-ReactNativeChat-ReactNativeChatTests.release.xcconfig */,
);
path = Pods;
sourceTree = "";
@@ -199,11 +200,11 @@
isa = PBXNativeTarget;
buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "ReactNativeChatTests" */;
buildPhases = (
- ECEBF6D927AD6913C7D49FAA /* [CP] Check Pods Manifest.lock */,
+ F8A669135F2AA86DB82558C7 /* [CP] Check Pods Manifest.lock */,
00E356EA1AD99517003FC87E /* Sources */,
00E356EB1AD99517003FC87E /* Frameworks */,
00E356EC1AD99517003FC87E /* Resources */,
- 96F29378CAD503EE24A4238F /* [CP] Copy Pods Resources */,
+ BBCE40C93F738CAC25638238 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -219,15 +220,15 @@
isa = PBXNativeTarget;
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "ReactNativeChat" */;
buildPhases = (
- C918B32D93F5DFC09167D222 /* [CP] Check Pods Manifest.lock */,
+ BD561FBF598A2868A469788D /* [CP] Check Pods Manifest.lock */,
FD10A7F022414F080027D42C /* Start Packager */,
13B07F871A680F5B00A75B9A /* Sources */,
13B07F8C1A680F5B00A75B9A /* Frameworks */,
13B07F8E1A680F5B00A75B9A /* Resources */,
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
- 5BB2824F6A06E2743CB8B76F /* [CP-User] [RNFB] Core Configuration */,
- F8A9FC2B4F4B70EAD371DCC7 /* [CP-User] [RNFB] Crashlytics Configuration */,
- 2BEB5135F1A6A0AFC39DEE60 /* [CP] Copy Pods Resources */,
+ B3F9394D94FC2E48E13823AD /* [CP] Copy Pods Resources */,
+ C00150F40DD23A06B9111196 /* [CP-User] [RNFB] Core Configuration */,
+ 7876F9D130A277A31FD2253C /* [CP-User] [RNFB] Crashlytics Configuration */,
);
buildRules = (
);
@@ -292,6 +293,7 @@
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */,
0F5BE0CE252686330097D869 /* GoogleService-Info.plist in Resources */,
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
+ E9DF872D2525201700607FDC /* AirshipConfig.plist in Resources */,
12DD1878FCB9487C9F031C86 /* GTAmericaExpMono-Rg.otf in Resources */,
1E76D5212522316A005A268F /* GTAmericaExp-Bold.otf in Resources */,
1E76D5222522316A005A268F /* GTAmericaExp-Light.otf in Resources */,
@@ -321,17 +323,137 @@
shellPath = /bin/sh;
shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh";
};
- 2BEB5135F1A6A0AFC39DEE60 /* [CP] Copy Pods Resources */ = {
+ 7876F9D130A277A31FD2253C /* [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";
+ };
+ B3F9394D94FC2E48E13823AD /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-ReactNativeChat/Pods-ReactNativeChat-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",
+ "${PODS_ROOT}/Airship/Airship/AirshipAutomation/Resources/UAInAppMessageButtonView.xib",
+ "${PODS_ROOT}/Airship/Airship/AirshipAutomation/Resources/UAInAppMessageFullScreenViewController.xib",
+ "${PODS_ROOT}/Airship/Airship/AirshipAutomation/Resources/UAInAppMessageHTMLViewController.xib",
+ "${PODS_ROOT}/Airship/Airship/AirshipAutomation/Resources/UAInAppMessageModalViewController.xib",
+ "${PODS_ROOT}/Airship/Airship/AirshipAutomation/Resources/UAInAppMessageResizableViewController.xib",
+ "${PODS_ROOT}/Airship/Airship/AirshipAutomation/Resources/UAAutomation.xcdatamodeld",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/ar.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/cs.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/da.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/de.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/en.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/es-419.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/es.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/fi.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/fr.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/hi.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/hu.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/id.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/it.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/iw.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/ja.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/ko.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/ms.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/nl.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/no.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/pl.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/pt-PT.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/pt.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/ro.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/ru.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/sk.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/sv.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/th.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/tr.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/UAEvents.xcdatamodeld",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/UARemoteData.xcdatamodeld",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/vi.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/zh-Hans.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/zh-Hant.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/ios/UADefaultActions.plist",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/ios/UANativeBridge",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/ios/UANotificationCategories.plist",
+ "${PODS_ROOT}/Airship/Airship/AirshipExtendedActions/Resources/UAExtendedActions.plist",
+ "${PODS_ROOT}/Airship/Airship/AirshipExtendedActions/Resources/UARateAppPromptView.xib",
+ "${PODS_ROOT}/Airship/Airship/AirshipMessageCenter/Resources/UADefaultMessageCenterListViewController.xib",
+ "${PODS_ROOT}/Airship/Airship/AirshipMessageCenter/Resources/UADefaultMessageCenterMessageViewController.xib",
+ "${PODS_ROOT}/Airship/Airship/AirshipMessageCenter/Resources/UAMessageCenterActions.plist",
+ "${PODS_ROOT}/Airship/Airship/AirshipMessageCenter/Resources/UAMessageCenterListCell.xib",
+ "${PODS_ROOT}/Airship/Airship/AirshipMessageCenter/Resources/UAMessageCenterListViewController.xib",
+ "${PODS_ROOT}/Airship/Airship/AirshipMessageCenter/Resources/UAMessageCenterMessageViewController.xib",
+ "${PODS_ROOT}/Airship/Airship/AirshipMessageCenter/Resources/UAMessageCenterPlaceholderIcon.png",
+ "${PODS_ROOT}/Airship/Airship/AirshipMessageCenter/Resources/UAInbox.xcdatamodeld",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAAutomationActions.plist",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAInAppMessageBannerContentView.nib",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAInAppMessageBannerView.nib",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAInAppMessageButtonView.nib",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAInAppMessageFullScreenViewController.nib",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAInAppMessageHTMLViewController.nib",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAInAppMessageModalViewController.nib",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAInAppMessageResizableViewController.nib",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAAutomation.momd",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ar.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/cs.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/da.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/de.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/en.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/es-419.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/es.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/fi.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/fr.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/hi.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/hu.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/id.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/it.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/iw.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ja.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ko.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ms.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/nl.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/no.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/pl.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/pt-PT.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/pt.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ro.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ru.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/sk.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/sv.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/th.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/tr.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAEvents.momd",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UARemoteData.momd",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/vi.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/zh-Hans.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/zh-Hant.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UADefaultActions.plist",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UANativeBridge",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UANotificationCategories.plist",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAExtendedActions.plist",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UARateAppPromptView.nib",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UADefaultMessageCenterListViewController.nib",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UADefaultMessageCenterMessageViewController.nib",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAMessageCenterActions.plist",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAMessageCenterListCell.nib",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAMessageCenterListViewController.nib",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAMessageCenterMessageViewController.nib",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAMessageCenterPlaceholderIcon.png",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAInbox.momd",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
@@ -339,27 +461,127 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeChat/Pods-ReactNativeChat-resources.sh\"\n";
showEnvVarsInLog = 0;
};
- 5BB2824F6A06E2743CB8B76F /* [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";
- };
- 96F29378CAD503EE24A4238F /* [CP] Copy Pods Resources */ = {
+ BBCE40C93F738CAC25638238 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-ReactNativeChat-ReactNativeChatTests/Pods-ReactNativeChat-ReactNativeChatTests-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",
+ "${PODS_ROOT}/Airship/Airship/AirshipAutomation/Resources/UAInAppMessageButtonView.xib",
+ "${PODS_ROOT}/Airship/Airship/AirshipAutomation/Resources/UAInAppMessageFullScreenViewController.xib",
+ "${PODS_ROOT}/Airship/Airship/AirshipAutomation/Resources/UAInAppMessageHTMLViewController.xib",
+ "${PODS_ROOT}/Airship/Airship/AirshipAutomation/Resources/UAInAppMessageModalViewController.xib",
+ "${PODS_ROOT}/Airship/Airship/AirshipAutomation/Resources/UAInAppMessageResizableViewController.xib",
+ "${PODS_ROOT}/Airship/Airship/AirshipAutomation/Resources/UAAutomation.xcdatamodeld",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/ar.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/cs.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/da.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/de.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/en.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/es-419.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/es.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/fi.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/fr.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/hi.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/hu.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/id.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/it.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/iw.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/ja.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/ko.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/ms.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/nl.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/no.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/pl.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/pt-PT.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/pt.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/ro.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/ru.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/sk.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/sv.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/th.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/tr.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/UAEvents.xcdatamodeld",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/UARemoteData.xcdatamodeld",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/vi.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/zh-Hans.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/common/zh-Hant.lproj",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/ios/UADefaultActions.plist",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/ios/UANativeBridge",
+ "${PODS_ROOT}/Airship/Airship/AirshipCore/Resources/ios/UANotificationCategories.plist",
+ "${PODS_ROOT}/Airship/Airship/AirshipExtendedActions/Resources/UAExtendedActions.plist",
+ "${PODS_ROOT}/Airship/Airship/AirshipExtendedActions/Resources/UARateAppPromptView.xib",
+ "${PODS_ROOT}/Airship/Airship/AirshipMessageCenter/Resources/UADefaultMessageCenterListViewController.xib",
+ "${PODS_ROOT}/Airship/Airship/AirshipMessageCenter/Resources/UADefaultMessageCenterMessageViewController.xib",
+ "${PODS_ROOT}/Airship/Airship/AirshipMessageCenter/Resources/UAMessageCenterActions.plist",
+ "${PODS_ROOT}/Airship/Airship/AirshipMessageCenter/Resources/UAMessageCenterListCell.xib",
+ "${PODS_ROOT}/Airship/Airship/AirshipMessageCenter/Resources/UAMessageCenterListViewController.xib",
+ "${PODS_ROOT}/Airship/Airship/AirshipMessageCenter/Resources/UAMessageCenterMessageViewController.xib",
+ "${PODS_ROOT}/Airship/Airship/AirshipMessageCenter/Resources/UAMessageCenterPlaceholderIcon.png",
+ "${PODS_ROOT}/Airship/Airship/AirshipMessageCenter/Resources/UAInbox.xcdatamodeld",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAAutomationActions.plist",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAInAppMessageBannerContentView.nib",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAInAppMessageBannerView.nib",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAInAppMessageButtonView.nib",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAInAppMessageFullScreenViewController.nib",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAInAppMessageHTMLViewController.nib",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAInAppMessageModalViewController.nib",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAInAppMessageResizableViewController.nib",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAAutomation.momd",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ar.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/cs.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/da.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/de.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/en.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/es-419.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/es.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/fi.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/fr.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/hi.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/hu.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/id.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/it.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/iw.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ja.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ko.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ms.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/nl.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/no.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/pl.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/pt-PT.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/pt.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ro.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ru.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/sk.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/sv.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/th.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/tr.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAEvents.momd",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UARemoteData.momd",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/vi.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/zh-Hans.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/zh-Hant.lproj",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UADefaultActions.plist",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UANativeBridge",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UANotificationCategories.plist",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAExtendedActions.plist",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UARateAppPromptView.nib",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UADefaultMessageCenterListViewController.nib",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UADefaultMessageCenterMessageViewController.nib",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAMessageCenterActions.plist",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAMessageCenterListCell.nib",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAMessageCenterListViewController.nib",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAMessageCenterMessageViewController.nib",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAMessageCenterPlaceholderIcon.png",
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/UAInbox.momd",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
@@ -367,7 +589,7 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeChat-ReactNativeChatTests/Pods-ReactNativeChat-ReactNativeChatTests-resources.sh\"\n";
showEnvVarsInLog = 0;
};
- C918B32D93F5DFC09167D222 /* [CP] Check Pods Manifest.lock */ = {
+ BD561FBF598A2868A469788D /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -389,7 +611,17 @@
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;
};
- ECEBF6D927AD6913C7D49FAA /* [CP] Check Pods Manifest.lock */ = {
+ C00150F40DD23A06B9111196 /* [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";
+ };
+ F8A669135F2AA86DB82558C7 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -411,16 +643,6 @@
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;
};
- F8A9FC2B4F4B70EAD371DCC7 /* [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;
@@ -473,7 +695,7 @@
/* Begin XCBuildConfiguration section */
00E356F61AD99517003FC87E /* Debug */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = BB3B578785B6B7D4E739A8C8 /* Pods-ReactNativeChat-ReactNativeChatTests.debug.xcconfig */;
+ baseConfigurationReference = 2656E49219DD99C2A26000B3 /* Pods-ReactNativeChat-ReactNativeChatTests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
@@ -482,7 +704,7 @@
"$(inherited)",
);
INFOPLIST_FILE = ReactNativeChatTests/Info.plist;
- IPHONEOS_DEPLOYMENT_TARGET = 10.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
OTHER_LDFLAGS = (
"-ObjC",
@@ -497,13 +719,13 @@
};
00E356F71AD99517003FC87E /* Release */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = B81A8F09B6065AF7D0A5D2CD /* Pods-ReactNativeChat-ReactNativeChatTests.release.xcconfig */;
+ baseConfigurationReference = C0FF5FF7940AEF7E12B34F6D /* Pods-ReactNativeChat-ReactNativeChatTests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
INFOPLIST_FILE = ReactNativeChatTests/Info.plist;
- IPHONEOS_DEPLOYMENT_TARGET = 10.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
OTHER_LDFLAGS = (
"-ObjC",
@@ -518,7 +740,7 @@
};
13B07F941A680F5B00A75B9A /* Debug */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 66FC9F8F0AF1190BE595FC04 /* Pods-ReactNativeChat.debug.xcconfig */;
+ baseConfigurationReference = 3836C07D427AF7E81680B81E /* Pods-ReactNativeChat.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
@@ -548,7 +770,7 @@
};
13B07F951A680F5B00A75B9A /* Release */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 2061509B833DB0123E4416F5 /* Pods-ReactNativeChat.release.xcconfig */;
+ baseConfigurationReference = A64B7A5E2FB2ADF3F0DB4820 /* Pods-ReactNativeChat.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
@@ -621,7 +843,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 10.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = "/usr/lib/swift $(inherited)";
LIBRARY_SEARCH_PATHS = (
"\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
@@ -674,7 +896,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 10.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = "/usr/lib/swift $(inherited)";
LIBRARY_SEARCH_PATHS = (
"\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
diff --git a/ios/ReactNativeChat/Info.plist b/ios/ReactNativeChat/Info.plist
index e192eeec19c48..166936d0835cc 100644
--- a/ios/ReactNativeChat/Info.plist
+++ b/ios/ReactNativeChat/Info.plist
@@ -23,28 +23,28 @@
CFBundleVersion
132
ITSAppUsesNonExemptEncryption
-
+
LSRequiresIPhoneOS
-
+
NSAppTransportSecurity
NSAllowsArbitraryLoads
-
+
NSExceptionDomains
localhost
NSExceptionAllowsInsecureHTTPLoads
-
+
NSIncludesSubdomains
-
+
www.expensify.com.dev
NSExceptionAllowsInsecureHTTPLoads
-
+
NSIncludesSubdomains
-
+
@@ -86,6 +86,6 @@
UIInterfaceOrientationPortraitUpsideDown
UIViewControllerBasedStatusBarAppearance
-
+
diff --git a/package-lock.json b/package-lock.json
index 345a115f5b05f..f173776d81d2e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -17743,6 +17743,11 @@
}
}
},
+ "urbanairship-react-native": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/urbanairship-react-native/-/urbanairship-react-native-8.1.0.tgz",
+ "integrity": "sha512-iyw32YwoXz7lrng2W5D+l+S4tgGx64Mi4h9qtQQLXyjXDZMtt73T8Sv6+W4KxyHq+YfbkAlWhYDCaTsN33dq/w=="
+ },
"uri-js": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
diff --git a/package.json b/package.json
index 06552ce0150d7..0caabe9a34311 100644
--- a/package.json
+++ b/package.json
@@ -58,7 +58,8 @@
"react-router-native": "^5.2.0",
"react-web-config": "^1.0.0",
"save": "^2.4.0",
- "underscore": "^1.10.2"
+ "underscore": "^1.10.2",
+ "urbanairship-react-native": "^8.1.0"
},
"devDependencies": {
"@babel/core": "^7.11.1",
diff --git a/src/IONKEYS.js b/src/IONKEYS.js
index b98f91925a246..d05c5f0d8e1ee 100644
--- a/src/IONKEYS.js
+++ b/src/IONKEYS.js
@@ -12,6 +12,7 @@ export default {
NETWORK: 'network',
PERSONAL_DETAILS: 'personalDetails',
SESSION: 'session',
+ IS_SIDEBAR_SHOWN: 'isSidebarShown',
// Collection Keys
COLLECTION: {
diff --git a/src/libs/API.js b/src/libs/API.js
index 22167e56515ba..ea5a11ce78e76 100644
--- a/src/libs/API.js
+++ b/src/libs/API.js
@@ -9,6 +9,7 @@ import ROUTES from '../ROUTES';
import Str from './Str';
import guid from './guid';
import redirectToSignIn from './actions/SignInRedirect';
+import PushNotification from './Notification/PushNotification';
// Queue for network requests so we don't lose actions done by the user while offline
let networkRequestQueue = [];
@@ -122,8 +123,9 @@ function createLogin(login, password) {
* @param {string} exitTo
*/
function setSuccessfulSignInData(data, exitTo) {
- const redirectTo = exitTo ? Str.normalizeUrl(exitTo) : ROUTES.ROOT;
+ PushNotification.register(data.accountID);
+ const redirectTo = exitTo ? Str.normalizeUrl(exitTo) : ROUTES.ROOT;
Ion.multiSet({
[IONKEYS.SESSION]: _.pick(data, 'authToken', 'accountID', 'email'),
[IONKEYS.APP_REDIRECT_TO]: redirectTo
diff --git a/src/libs/Ion.js b/src/libs/Ion.js
index ee6b140cb5db2..16f21901f9c4d 100644
--- a/src/libs/Ion.js
+++ b/src/libs/Ion.js
@@ -24,7 +24,7 @@ const evictionBlocklist = {};
* Get some data from the store
*
* @param {string} key
- * @returns {*}
+ * @returns {Promise<*>}
*/
function get(key) {
return AsyncStorage.getItem(key)
@@ -346,7 +346,7 @@ function multiSet(data) {
/**
* Clear out all the data in the store
*
- * @returns {Promise}
+ * @returns {Promise}
*/
function clear() {
return AsyncStorage.clear();
diff --git a/src/libs/Notification/BrowserNotifications.js b/src/libs/Notification/LocalNotification/BrowserNotifications.js
similarity index 97%
rename from src/libs/Notification/BrowserNotifications.js
rename to src/libs/Notification/LocalNotification/BrowserNotifications.js
index c5c52dccf9ebe..84b6a8990388d 100644
--- a/src/libs/Notification/BrowserNotifications.js
+++ b/src/libs/Notification/LocalNotification/BrowserNotifications.js
@@ -1,6 +1,6 @@
-// Web and desktop implementation only. Do not import for direct use. Use Notification.
-import Str from '../Str';
-import CONST from '../../CONST';
+// Web and desktop implementation only. Do not import for direct use. Use LocalNotification.
+import Str from '../../Str';
+import CONST from '../../../CONST';
const EXPENSIFY_ICON_URL = `${CONST.CLOUDFRONT_URL}/images/favicon-2019.png`;
const DEFAULT_DELAY = 4000;
diff --git a/src/libs/Notification/index.js b/src/libs/Notification/LocalNotification/index.js
similarity index 100%
rename from src/libs/Notification/index.js
rename to src/libs/Notification/LocalNotification/index.js
diff --git a/src/libs/Notification/LocalNotification/index.native.js b/src/libs/Notification/LocalNotification/index.native.js
new file mode 100644
index 0000000000000..8dca0ebb7537e
--- /dev/null
+++ b/src/libs/Notification/LocalNotification/index.native.js
@@ -0,0 +1,4 @@
+// Local Notifications are not currently supported on mobile so we'll just noop here.
+export default {
+ showCommentNotification: () => {},
+};
diff --git a/src/libs/Notification/PushNotification/NotificationType.js b/src/libs/Notification/PushNotification/NotificationType.js
new file mode 100644
index 0000000000000..1afa89d002013
--- /dev/null
+++ b/src/libs/Notification/PushNotification/NotificationType.js
@@ -0,0 +1,7 @@
+/**
+ * See https://github.com/Expensify/Web-Expensify/blob/master/lib/MobilePushNotifications.php for the various
+ * types of push notifications sent by our API.
+ */
+export default {
+ REPORT_COMMENT: 'reportComment',
+};
diff --git a/src/libs/Notification/PushNotification/index.js b/src/libs/Notification/PushNotification/index.js
new file mode 100644
index 0000000000000..ad8c27a5ddbac
--- /dev/null
+++ b/src/libs/Notification/PushNotification/index.js
@@ -0,0 +1,10 @@
+import NotificationType from './NotificationType';
+
+// Push notifications are only supported on mobile, so we'll just noop here
+export default {
+ register: () => {},
+ deregister: () => {},
+ onReceived: () => {},
+ onSelected: () => {},
+ TYPE: NotificationType,
+};
diff --git a/src/libs/Notification/PushNotification/index.native.js b/src/libs/Notification/PushNotification/index.native.js
new file mode 100644
index 0000000000000..2f48f8f921918
--- /dev/null
+++ b/src/libs/Notification/PushNotification/index.native.js
@@ -0,0 +1,149 @@
+import _ from 'underscore';
+import {AppState} from 'react-native';
+import {UrbanAirship, EventType} from 'urbanairship-react-native';
+import lodashGet from 'lodash.get';
+import NotificationType from './NotificationType';
+
+const notificationEventActionMap = {};
+
+/**
+ * Handle a push notification event, and trigger and bound actions.
+ *
+ * @param {string} eventType
+ * @param {object} notification
+ */
+function pushNotificationEventCallback(eventType, notification) {
+ const actionMap = notificationEventActionMap[eventType] || {};
+ let payload = lodashGet(notification, 'extras.payload');
+
+ // On Android, some notification payloads are sent as a JSON string rather than an object
+ if (_.isString(payload)) {
+ payload = JSON.parse(payload);
+ }
+
+ console.debug(`[PUSH_NOTIFICATION] ${eventType}`, {
+ title: notification.title,
+ message: notification.alert,
+ payload
+ });
+
+ if (!payload) {
+ console.debug('[PUSH_NOTIFICATION] Notification has null or undefined payload, not executing any callback.');
+ 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.
+ // Note: We hope to prevent foreground notifications from appearing in the near future,
+ // so when that happens we can go back to ignoring all push notification callbacks when the app is in the foreground
+ if (AppState.currentState === 'active' && eventType === EventType.PushReceived) {
+ 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;
+ }
+
+ const action = actionMap[payload.type];
+ if (!action) {
+ console.debug('[PUSH_NOTIFICATION] No callback set up: ', {
+ event: eventType,
+ notificationType: payload.type,
+ });
+ return;
+ }
+ action(payload);
+}
+
+/**
+ * Register this device for push notifications for the given accountID.
+ *
+ * @param {string|int} accountID
+ */
+function register(accountID) {
+ // Get permissions to display push notifications (prompts user on iOS, but not Android)
+ UrbanAirship.enableUserPushNotifications()
+ .then((isEnabled) => {
+ if (!isEnabled) {
+ 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) => {
+ 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);
+ });
+}
+
+/**
+ * Deregister this device from push notifications.
+ */
+function deregister() {
+ console.debug('[PUSH_NOTIFICATIONS] Unsubscribing from push notifications.');
+ UrbanAirship.setNamedUser(null);
+ UrbanAirship.removeAllListeners(EventType.PushReceived);
+ UrbanAirship.removeAllListeners(EventType.NotificationResponse);
+}
+
+/**
+ * Bind a callback to a push notification of a given type.
+ * See https://github.com/Expensify/Web-Expensify/blob/master/lib/MobilePushNotifications.php for the various
+ * types of push notifications sent, along with the data that they provide.
+ *
+ * Note: This implementation allows for only one callback to be bound to an Event/Type pair. For example,
+ * if we attempt to bind two callbacks to the PushReceived event for reportComment notifications,
+ * the second will overwrite the first.
+ *
+ * @param {string} notificationType
+ * @param {Function} callback
+ * @param {string?} triggerEvent - The event that should trigger this callback. Should be one of UrbanAirship.EventType
+ */
+function bind(notificationType, callback, triggerEvent) {
+ if (!notificationEventActionMap[triggerEvent]) {
+ notificationEventActionMap[triggerEvent] = {};
+ }
+ notificationEventActionMap[triggerEvent][notificationType] = callback;
+}
+
+/**
+ * Bind a callback to be executed when a push notification of a given type is received.
+ *
+ * @param {string} notificationType
+ * @param {Function} callback
+ */
+function onReceived(notificationType, callback) {
+ bind(notificationType, callback, EventType.PushReceived);
+}
+
+/**
+ * Bind a callback to be executed when a push notification of a given type is tapped by the user.
+ *
+ * @param {string} notificationType
+ * @param {Function} callback
+ */
+function onSelected(notificationType, callback) {
+ bind(notificationType, callback, EventType.NotificationResponse);
+}
+
+export default {
+ register,
+ deregister,
+ onReceived,
+ onSelected,
+ TYPE: NotificationType,
+};
diff --git a/src/libs/Notification/index.native.js b/src/libs/Notification/index.native.js
deleted file mode 100644
index e1b798612c610..0000000000000
--- a/src/libs/Notification/index.native.js
+++ /dev/null
@@ -1,4 +0,0 @@
-// Browser Notifications are not supported on mobile so we'll just noop here.
-export default {
- showCommentNotification: () => {},
-};
diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js
index fffee9249d487..94959beb2145a 100644
--- a/src/libs/actions/Report.js
+++ b/src/libs/actions/Report.js
@@ -6,13 +6,15 @@ import Ion from '../Ion';
import * as API from '../API';
import IONKEYS from '../../IONKEYS';
import * as Pusher from '../Pusher/pusher';
-import Notification from '../Notification';
+import LocalNotification from '../Notification/LocalNotification';
+import PushNotification from '../Notification/PushNotification';
import * as PersonalDetails from './PersonalDetails';
import {redirect} from './App';
import * as ActiveClientManager from '../ActiveClientManager';
import Visibility from '../Visibility';
import ROUTES from '../../ROUTES';
import NetworkConnection from '../NetworkConnection';
+import {hide as hideSidebar} from './Sidebar';
let currentUserEmail;
let currentUserAccountID;
@@ -195,24 +197,24 @@ function updateReportWithNewAction(reportID, reportAction) {
});
if (!ActiveClientManager.isClientTheLeader()) {
- console.debug('[NOTIFICATION] Skipping notification because this client is not the leader');
+ console.debug('[LOCAL_NOTIFICATION] Skipping notification because this client is not the leader');
return;
}
// If this comment is from the current user we don't want to parrot whatever they wrote back to them.
if (reportAction.actorAccountID === currentUserAccountID) {
- console.debug('[NOTIFICATION] No notification because comment is from the currently logged in user');
+ console.debug('[LOCAL_NOTIFICATION] No notification because comment is from the currently logged in user');
return;
}
// If we are currently viewing this report do not show a notification.
if (reportID === lastViewedReportID && Visibility.isVisible()) {
- console.debug('[NOTIFICATION] No notification because it was a comment for the current report');
+ console.debug('[LOCAL_NOTIFICATION] No notification because it was a comment for the current report');
return;
}
- console.debug('[NOTIFICATION] Creating notification');
- Notification.showCommentNotification({
+ console.debug('[LOCAL_NOTIFICATION] Creating notification');
+ LocalNotification.showCommentNotification({
reportAction,
onClick: () => {
// Navigate to this report onClick
@@ -248,6 +250,16 @@ function subscribeToReportCommentEvents() {
Pusher.subscribe(pusherChannelName, 'reportComment', (pushJSON) => {
updateReportWithNewAction(pushJSON.reportID, pushJSON.reportAction);
});
+
+ PushNotification.onReceived(PushNotification.TYPE.REPORT_COMMENT, ({reportID, reportAction}) => {
+ updateReportWithNewAction(reportID, reportAction);
+ });
+
+ // Open correct report when push notification is clicked
+ PushNotification.onSelected(PushNotification.TYPE.REPORT_COMMENT, ({reportID}) => {
+ redirect(ROUTES.getReportRoute(reportID));
+ hideSidebar();
+ });
}
/**
diff --git a/src/libs/actions/Sidebar.js b/src/libs/actions/Sidebar.js
new file mode 100644
index 0000000000000..5c8789dd058d2
--- /dev/null
+++ b/src/libs/actions/Sidebar.js
@@ -0,0 +1,21 @@
+import Ion from '../Ion';
+import IONKEYS from '../../IONKEYS';
+
+/**
+ * Hide the sidebar, if it is shown.
+ */
+function hide() {
+ Ion.set(IONKEYS.IS_SIDEBAR_SHOWN, false);
+}
+
+/**
+ * Show the sidebar, if it is hidden.
+ */
+function show() {
+ Ion.set(IONKEYS.IS_SIDEBAR_SHOWN, true);
+}
+
+export {
+ hide,
+ show,
+};
diff --git a/src/libs/actions/SignInRedirect.js b/src/libs/actions/SignInRedirect.js
index 973a6461014f3..a7c8f14e6302a 100644
--- a/src/libs/actions/SignInRedirect.js
+++ b/src/libs/actions/SignInRedirect.js
@@ -5,6 +5,7 @@ import {redirect} from './App';
import * as Pusher from '../Pusher/pusher';
import NetworkConnection from '../NetworkConnection';
import UnreadIndicatorUpdater from '../UnreadIndicatorUpdater';
+import PushNotification from '../Notification/PushNotification';
let currentURL;
Ion.connect({
@@ -21,6 +22,7 @@ Ion.connect({
function redirectToSignIn(errorMessage) {
NetworkConnection.stopListeningForReconnect();
UnreadIndicatorUpdater.stopListeningForReportChanges();
+ PushNotification.deregister();
Pusher.disconnect();
Ion.clear()
.then(() => {
diff --git a/src/pages/home/HomePage.js b/src/pages/home/HomePage.js
index 7446698f5c4c6..a3bef18cf6ce6 100644
--- a/src/pages/home/HomePage.js
+++ b/src/pages/home/HomePage.js
@@ -1,4 +1,5 @@
import React from 'react';
+import PropTypes from 'prop-types';
import {
StatusBar,
View,
@@ -7,12 +8,14 @@ import {
Easing,
Keyboard
} from 'react-native';
+import _ from 'underscore';
import {SafeAreaInsetsContext, SafeAreaProvider} from 'react-native-safe-area-context';
import {Route} from '../../libs/Router';
import styles, {getSafeAreaPadding} from '../../styles/StyleSheet';
import Header from './HeaderView';
import Sidebar from './sidebar/SidebarView';
import Main from './MainView';
+import {hide as hideSidebar, show as showSidebar} from '../../libs/actions/Sidebar';
import {
subscribeToReportCommentEvents,
fetchAll as fetchAllReports,
@@ -22,17 +25,25 @@ import {fetch as fetchPersonalDetails} from '../../libs/actions/PersonalDetails'
import * as Pusher from '../../libs/Pusher/pusher';
import UnreadIndicatorUpdater from '../../libs/UnreadIndicatorUpdater';
import ROUTES from '../../ROUTES';
+import IONKEYS from '../../IONKEYS';
+import withIon from '../../components/withIon';
import NetworkConnection from '../../libs/NetworkConnection';
const windowSize = Dimensions.get('window');
const widthBreakPoint = 1000;
-export default class App extends React.Component {
+const propTypes = {
+ isSidebarShown: PropTypes.bool,
+};
+const defaultProps = {
+ isSidebarShown: true,
+};
+
+class App extends React.Component {
constructor(props) {
super(props);
this.state = {
- hamburgerShown: true,
isHamburgerEnabled: windowSize.width <= widthBreakPoint,
};
@@ -40,7 +51,12 @@ export default class App extends React.Component {
this.dismissHamburger = this.dismissHamburger.bind(this);
this.showHamburger = this.showHamburger.bind(this);
this.toggleHamburgerBasedOnDimensions = this.toggleHamburgerBasedOnDimensions.bind(this);
- this.animationTranslateX = new Animated.Value(!this.state.hamburgerShown ? -300 : 0);
+
+ // Note: This null check is only necessary because withIon passes null for bound props
+ // that are null-initialized initialized in Ion, and defaultProps only replaces for `undefined` values
+ this.animationTranslateX = new Animated.Value(
+ !_.isNull(props.isSidebarShown) && !props.isSidebarShown ? -300 : 0
+ );
}
componentDidMount() {
@@ -63,6 +79,14 @@ export default class App extends React.Component {
StatusBar.setTranslucent(true);
}
+ componentDidUpdate(prevProps) {
+ if (this.props.isSidebarShown === prevProps.isSidebarShown) {
+ // Nothing changed, don't trigger animation or re-render
+ return;
+ }
+ this.animateHamburger(prevProps.isSidebarShown);
+ }
+
componentWillUnmount() {
Dimensions.removeEventListener('change', this.toggleHamburgerBasedOnDimensions);
}
@@ -73,10 +97,10 @@ export default class App extends React.Component {
*/
toggleHamburgerBasedOnDimensions({window: changedWindow}) {
this.setState({isHamburgerEnabled: changedWindow.width <= widthBreakPoint});
- if (!this.state.hamburgerShown && changedWindow.width > widthBreakPoint) {
- this.setState({hamburgerShown: true});
- } else if (this.state.hamburgerShown && changedWindow.width < widthBreakPoint) {
- this.setState({hamburgerShown: false});
+ if (!this.props.isSidebarShown && changedWindow.width > widthBreakPoint) {
+ showSidebar();
+ } else if (this.props.isSidebarShown && changedWindow.width < widthBreakPoint) {
+ hideSidebar();
}
}
@@ -86,7 +110,7 @@ export default class App extends React.Component {
* Only changes hamburger state on small screens (e.g. Mobile and mWeb)
*/
dismissHamburger() {
- if (!this.state.hamburgerShown) {
+ if (!this.props.isSidebarShown) {
return;
}
@@ -99,7 +123,7 @@ export default class App extends React.Component {
* Only changes hamburger state on smaller screens (e.g. Mobile and mWeb)
*/
showHamburger() {
- if (this.state.hamburgerShown) {
+ if (this.props.isSidebarShown) {
return;
}
@@ -120,10 +144,8 @@ export default class App extends React.Component {
easing: Easing.ease,
useNativeDriver: false
}).start(({finished}) => {
- // If the hamburger is currently shown, we want to hide it only after the animation is complete
- // Otherwise, we can't see the animation
if (finished && hamburgerIsShown) {
- this.setState({hamburgerShown: false});
+ hideSidebar();
}
});
}
@@ -137,20 +159,21 @@ export default class App extends React.Component {
return;
}
- const hamburgerIsShown = this.state.hamburgerShown;
-
- // If the hamburger currently is not shown, we want to immediately make it visible for the animation
- if (!hamburgerIsShown) {
- this.setState({hamburgerShown: true});
+ // If the hamburger currently is not shown, we want to make it visible before the animation
+ if (!this.props.isSidebarShown) {
+ showSidebar();
+ return;
}
+
+ // Otherwise, we want to hide it after the animation
Keyboard.dismiss();
- this.animateHamburger(hamburgerIsShown);
+ this.animateHamburger(true);
}
render() {
- const hamburgerStyle = this.state.isHamburgerEnabled && this.state.hamburgerShown
+ const hamburgerStyle = this.state.isHamburgerEnabled && this.props.isSidebarShown
? styles.hamburgerOpenAbsolute : styles.hamburgerOpen;
- const visibility = this.state.hamburgerShown ? styles.dFlex : styles.dNone;
+ const visibility = !this.state.isHamburgerEnabled || this.props.isSidebarShown ? styles.dFlex : styles.dNone;
const appContentWrapperStyle = !this.state.isHamburgerEnabled ? styles.appContentWrapperLarge : null;
const appContentStyle = !this.state.isHamburgerEnabled ? styles.appContentRounded : null;
return (
@@ -198,3 +221,14 @@ export default class App extends React.Component {
);
}
}
+
+App.propTypes = propTypes;
+App.defaultProps = defaultProps;
+
+export default withIon(
+ {
+ isSidebarShown: {
+ key: IONKEYS.IS_SIDEBAR_SHOWN
+ },
+ },
+)(App);