diff --git a/desktop/ELECTRON_EVENTS.js b/desktop/ELECTRON_EVENTS.js new file mode 100644 index 0000000000000..d2ce638689865 --- /dev/null +++ b/desktop/ELECTRON_EVENTS.js @@ -0,0 +1,6 @@ +const ELECTRON_EVENTS = { + REQUEST_UPDATE_BADGE_COUNT: 'requestUpdateBadgeCount', + REQUEST_VISIBILITY: 'requestVisibility', +}; + +module.exports = ELECTRON_EVENTS; diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 8228bcb2ae0ee..8c1457e58c0e9 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -310,6 +310,8 @@ PODS: - React-jsi (= 0.63.3) - RNCAsyncStorage (1.11.0): - React + - RNCPushNotificationIOS (1.5.0): + - React - Yoga (1.14.0) - YogaKit (1.18.1): - Yoga (~> 1.14) @@ -367,6 +369,7 @@ DEPENDENCIES: - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`) - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) - "RNCAsyncStorage (from `../node_modules/@react-native-community/async-storage`)" + - "RNCPushNotificationIOS (from `../node_modules/@react-native-community/push-notification-ios`)" - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) SPEC REPOS: @@ -447,6 +450,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native/ReactCommon" RNCAsyncStorage: :path: "../node_modules/@react-native-community/async-storage" + RNCPushNotificationIOS: + :path: "../node_modules/@react-native-community/push-notification-ios" Yoga: :path: "../node_modules/react-native/ReactCommon/yoga" @@ -493,6 +498,7 @@ SPEC CHECKSUMS: React-RCTVibration: 8e9fb25724a0805107fc1acc9075e26f814df454 ReactCommon: 4167844018c9ed375cc01a843e9ee564399e53c3 RNCAsyncStorage: db711e29e5e0500d9bd21aa0c2e397efa45302b1 + RNCPushNotificationIOS: 8025ff0b610d7b28d29ddc1b619cd55814362e4c Yoga: 7d13633d129fd179e01b8953d38d47be90db185a YogaKit: f782866e155069a2cca2517aafea43200b01fd5a diff --git a/ios/ReactNativeChat.xcodeproj/project.pbxproj b/ios/ReactNativeChat.xcodeproj/project.pbxproj index 635754ba7c490..a29afb3d97521 100644 --- a/ios/ReactNativeChat.xcodeproj/project.pbxproj +++ b/ios/ReactNativeChat.xcodeproj/project.pbxproj @@ -8,7 +8,6 @@ /* Begin PBXBuildFile section */ 00E356F31AD99517003FC87E /* ReactNativeChatTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* ReactNativeChatTests.m */; }; - 097C76E5807C5DFC565DC655 /* libPods-ReactNativeChat-ReactNativeChatTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C4F81DB9C6DA6418525441E5 /* 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 */; }; @@ -18,10 +17,11 @@ 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 */; }; - 347C4A976B972BC7A903F97D /* libPods-ReactNativeChat.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6ABF95746519766B23B4E2D0 /* libPods-ReactNativeChat.a */; }; - 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; 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 */; }; /* End PBXBuildFile section */ @@ -46,24 +46,25 @@ 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 = ""; }; - 1CFBC073CF30A72CCF109A40 /* 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 = ""; }; + 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 = ""; }; 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 = ""; }; - 6ABF95746519766B23B4E2D0 /* libPods-ReactNativeChat.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ReactNativeChat.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 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 = ""; }; 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 = ""; }; - 9B9FEA91E46D2B2609028E69 /* 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 = ""; }; + 918D7FEFF96242E6B5F5E14D /* GTAmericaExp-RgIt.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; 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 = undefined; 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 = ""; }; - BA6C613DE6755E40F7EDDC68 /* 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 = ""; }; - C4F81DB9C6DA6418525441E5 /* libPods-ReactNativeChat-ReactNativeChatTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ReactNativeChat-ReactNativeChatTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; - C6C1D4F5C262ACDAF1800CAD /* 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 = ""; }; + 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 = ""; }; + DB5A1365442D4419AF6F08E5 /* GTAmericaExp-MdIt.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = undefined; includeInIndex = 0; lastKnownFileType = unknown; name = "GTAmericaExp-MdIt.otf"; path = "../assets/fonts/GTAmericaExp-MdIt.otf"; 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; }; - A8D6F2F722FD4E66A38EBBB6 /* GTAmericaExp-BdIt.otf */ = {isa = PBXFileReference; name = "GTAmericaExp-BdIt.otf"; path = "../assets/fonts/GTAmericaExp-BdIt.otf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - DB5A1365442D4419AF6F08E5 /* GTAmericaExp-MdIt.otf */ = {isa = PBXFileReference; name = "GTAmericaExp-MdIt.otf"; path = "../assets/fonts/GTAmericaExp-MdIt.otf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - 918D7FEFF96242E6B5F5E14D /* GTAmericaExp-RgIt.otf */ = {isa = PBXFileReference; name = "GTAmericaExp-RgIt.otf"; path = "../assets/fonts/GTAmericaExp-RgIt.otf"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -71,7 +72,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 097C76E5807C5DFC565DC655 /* libPods-ReactNativeChat-ReactNativeChatTests.a in Frameworks */, + 712B637C71EDACB60BFCCFDF /* libPods-ReactNativeChat-ReactNativeChatTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -79,7 +80,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 347C4A976B972BC7A903F97D /* libPods-ReactNativeChat.a in Frameworks */, + 7EF88515CE8703E46E771C2D /* libPods-ReactNativeChat.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -106,6 +107,7 @@ 13B07FAE1A68108700A75B9A /* ReactNativeChat */ = { isa = PBXGroup; children = ( + 499D0486251AC7F1000B666B /* Chat.entitlements */, 008F07F21AC5B25A0029DE68 /* main.jsbundle */, 13B07FAF1A68108700A75B9A /* AppDelegate.h */, 13B07FB01A68108700A75B9A /* AppDelegate.m */, @@ -122,8 +124,8 @@ children = ( ED297162215061F000B7C4FE /* JavaScriptCore.framework */, ED2971642150620600B7C4FE /* JavaScriptCore.framework */, - 6ABF95746519766B23B4E2D0 /* libPods-ReactNativeChat.a */, - C4F81DB9C6DA6418525441E5 /* libPods-ReactNativeChat-ReactNativeChatTests.a */, + B2E64A28C6D8EC058C5C3144 /* libPods-ReactNativeChat.a */, + 5198B14DF64811534104106B /* libPods-ReactNativeChat-ReactNativeChatTests.a */, ); name = Frameworks; sourceTree = ""; @@ -179,10 +181,10 @@ EC29677F0A49C2946A495A33 /* Pods */ = { isa = PBXGroup; children = ( - 9B9FEA91E46D2B2609028E69 /* Pods-ReactNativeChat.debug.xcconfig */, - C6C1D4F5C262ACDAF1800CAD /* Pods-ReactNativeChat.release.xcconfig */, - BA6C613DE6755E40F7EDDC68 /* Pods-ReactNativeChat-ReactNativeChatTests.debug.xcconfig */, - 1CFBC073CF30A72CCF109A40 /* Pods-ReactNativeChat-ReactNativeChatTests.release.xcconfig */, + 66FC9F8F0AF1190BE595FC04 /* Pods-ReactNativeChat.debug.xcconfig */, + 2061509B833DB0123E4416F5 /* Pods-ReactNativeChat.release.xcconfig */, + BB3B578785B6B7D4E739A8C8 /* Pods-ReactNativeChat-ReactNativeChatTests.debug.xcconfig */, + B81A8F09B6065AF7D0A5D2CD /* Pods-ReactNativeChat-ReactNativeChatTests.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -194,11 +196,11 @@ isa = PBXNativeTarget; buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "ReactNativeChatTests" */; buildPhases = ( - 67625BD6E56D7B445CE0B75D /* [CP] Check Pods Manifest.lock */, + ECEBF6D927AD6913C7D49FAA /* [CP] Check Pods Manifest.lock */, 00E356EA1AD99517003FC87E /* Sources */, 00E356EB1AD99517003FC87E /* Frameworks */, 00E356EC1AD99517003FC87E /* Resources */, - 740ED6E57E4D77AE97454014 /* [CP] Copy Pods Resources */, + 96F29378CAD503EE24A4238F /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -214,13 +216,13 @@ isa = PBXNativeTarget; buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "ReactNativeChat" */; buildPhases = ( - 25778851D923FF95A2D6EE6D /* [CP] Check Pods Manifest.lock */, + C918B32D93F5DFC09167D222 /* [CP] Check Pods Manifest.lock */, FD10A7F022414F080027D42C /* Start Packager */, 13B07F871A680F5B00A75B9A /* Sources */, 13B07F8C1A680F5B00A75B9A /* Frameworks */, 13B07F8E1A680F5B00A75B9A /* Resources */, 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, - 930B6ED2A0414681598DB7E1 /* [CP] Copy Pods Resources */, + 2BEB5135F1A6A0AFC39DEE60 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -247,7 +249,7 @@ 13B07F861A680F5B00A75B9A = { DevelopmentTeam = 368M544MTT; LastSwiftMigration = 1120; - ProvisioningStyle = Manual; + ProvisioningStyle = Automatic; }; }; }; @@ -313,84 +315,84 @@ shellPath = /bin/sh; shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh"; }; - 25778851D923FF95A2D6EE6D /* [CP] Check Pods Manifest.lock */ = { + 2BEB5135F1A6A0AFC39DEE60 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); - inputFileListPaths = ( - ); inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-ReactNativeChat/Pods-ReactNativeChat-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle", ); + name = "[CP] Copy Pods Resources"; outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-ReactNativeChat-checkManifestLockResult.txt", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle", ); 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-ReactNativeChat/Pods-ReactNativeChat-resources.sh\"\n"; showEnvVarsInLog = 0; }; - 67625BD6E56D7B445CE0B75D /* [CP] Check Pods Manifest.lock */ = { + 96F29378CAD503EE24A4238F /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); - inputFileListPaths = ( - ); inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-ReactNativeChat-ReactNativeChatTests/Pods-ReactNativeChat-ReactNativeChatTests-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle", ); + name = "[CP] Copy Pods Resources"; outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-ReactNativeChat-ReactNativeChatTests-checkManifestLockResult.txt", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle", ); 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-ReactNativeChat-ReactNativeChatTests/Pods-ReactNativeChat-ReactNativeChatTests-resources.sh\"\n"; showEnvVarsInLog = 0; }; - 740ED6E57E4D77AE97454014 /* [CP] Copy Pods Resources */ = { + C918B32D93F5DFC09167D222 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); + inputFileListPaths = ( + ); inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ReactNativeChat-ReactNativeChatTests/Pods-ReactNativeChat-ReactNativeChatTests-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle", + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( ); - name = "[CP] Copy Pods Resources"; outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle", + "$(DERIVED_FILE_DIR)/Pods-ReactNativeChat-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeChat-ReactNativeChatTests/Pods-ReactNativeChat-ReactNativeChatTests-resources.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; }; - 930B6ED2A0414681598DB7E1 /* [CP] Copy Pods Resources */ = { + ECEBF6D927AD6913C7D49FAA /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); + inputFileListPaths = ( + ); inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-ReactNativeChat/Pods-ReactNativeChat-resources.sh", - "${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle", + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( ); - name = "[CP] Copy Pods Resources"; outputPaths = ( - "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle", + "$(DERIVED_FILE_DIR)/Pods-ReactNativeChat-ReactNativeChatTests-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ReactNativeChat/Pods-ReactNativeChat-resources.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; }; FD10A7F022414F080027D42C /* Start Packager */ = { @@ -445,7 +447,7 @@ /* Begin XCBuildConfiguration section */ 00E356F61AD99517003FC87E /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = BA6C613DE6755E40F7EDDC68 /* Pods-ReactNativeChat-ReactNativeChatTests.debug.xcconfig */; + baseConfigurationReference = BB3B578785B6B7D4E739A8C8 /* Pods-ReactNativeChat-ReactNativeChatTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -469,7 +471,7 @@ }; 00E356F71AD99517003FC87E /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 1CFBC073CF30A72CCF109A40 /* Pods-ReactNativeChat-ReactNativeChatTests.release.xcconfig */; + baseConfigurationReference = B81A8F09B6065AF7D0A5D2CD /* Pods-ReactNativeChat-ReactNativeChatTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; @@ -490,14 +492,15 @@ }; 13B07F941A680F5B00A75B9A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9B9FEA91E46D2B2609028E69 /* Pods-ReactNativeChat.debug.xcconfig */; + baseConfigurationReference = 66FC9F8F0AF1190BE595FC04 /* Pods-ReactNativeChat.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_ENTITLEMENTS = ReactNativeChat/Chat.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 3; - DEVELOPMENT_TEAM = 368M544MTT; + DEVELOPMENT_TEAM = ""; ENABLE_BITCODE = NO; INFOPLIST_FILE = ReactNativeChat/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -509,7 +512,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.chat.expensify.chat; PRODUCT_NAME = Chat; - PROVISIONING_PROFILE_SPECIFIER = chat_expensify_appstore; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -519,14 +522,15 @@ }; 13B07F951A680F5B00A75B9A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = C6C1D4F5C262ACDAF1800CAD /* Pods-ReactNativeChat.release.xcconfig */; + baseConfigurationReference = 2061509B833DB0123E4416F5 /* Pods-ReactNativeChat.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = "iPhone Distribution"; - CODE_SIGN_STYLE = Manual; + CODE_SIGN_ENTITLEMENTS = ReactNativeChat/Chat.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 3; - DEVELOPMENT_TEAM = 368M544MTT; + DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = ReactNativeChat/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; MARKETING_VERSION = 1.0.0; @@ -537,7 +541,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.chat.expensify.chat; PRODUCT_NAME = Chat; - PROVISIONING_PROFILE_SPECIFIER = chat_expensify_appstore; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; diff --git a/ios/ReactNativeChat/AppDelegate.h b/ios/ReactNativeChat/AppDelegate.h index ef1de86a2a80a..854a4484a587d 100644 --- a/ios/ReactNativeChat/AppDelegate.h +++ b/ios/ReactNativeChat/AppDelegate.h @@ -1,7 +1,8 @@ +#import #import #import -@interface AppDelegate : UIResponder +@interface AppDelegate : UIResponder @property (nonatomic, strong) UIWindow *window; diff --git a/ios/ReactNativeChat/AppDelegate.m b/ios/ReactNativeChat/AppDelegate.m index dab2afd4320e6..538c9c4267717 100644 --- a/ios/ReactNativeChat/AppDelegate.m +++ b/ios/ReactNativeChat/AppDelegate.m @@ -4,6 +4,9 @@ #import #import +#import +#import + #ifdef FB_SONARKIT_ENABLED #import #import @@ -43,9 +46,55 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( rootViewController.view = rootView; self.window.rootViewController = rootViewController; [self.window makeKeyAndVisible]; + + // 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(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge); +} + +// Required to register for notifications +- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings +{ + [RNCPushNotificationIOS didRegisterUserNotificationSettings:notificationSettings]; +} +// 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]; +} +// IOS 10+ Required for localNotification event +- (void)userNotificationCenter:(UNUserNotificationCenter *)center +didReceiveNotificationResponse:(UNNotificationResponse *)response + withCompletionHandler:(void (^)(void))completionHandler +{ + [RNCPushNotificationIOS didReceiveNotificationResponse:response]; + completionHandler(); +} +// IOS 4-10 Required for the localNotification event. +- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification +{ + [RNCPushNotificationIOS didReceiveLocalNotification:notification]; +} + - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge { #if DEBUG diff --git a/ios/ReactNativeChat/Chat.entitlements b/ios/ReactNativeChat/Chat.entitlements new file mode 100644 index 0000000000000..903def2af5306 --- /dev/null +++ b/ios/ReactNativeChat/Chat.entitlements @@ -0,0 +1,8 @@ + + + + + aps-environment + development + + diff --git a/ios/ReactNativeChat/Info.plist b/ios/ReactNativeChat/Info.plist index e5306d4c4a5ea..2b0c9ecdca4a1 100644 --- a/ios/ReactNativeChat/Info.plist +++ b/ios/ReactNativeChat/Info.plist @@ -68,6 +68,10 @@ GTAmericaExp-MdIt.otf GTAmericaExp-RgIt.otf + UIBackgroundModes + + remote-notification + UILaunchStoryboardName LaunchScreen UIRequiredDeviceCapabilities diff --git a/main.js b/main.js index 75d037eb33679..ad39e03dcc910 100644 --- a/main.js +++ b/main.js @@ -8,6 +8,7 @@ const serve = require('electron-serve'); const contextMenu = require('electron-context-menu'); const {autoUpdater} = require('electron-updater'); const log = require('electron-log'); +const ELECTRON_EVENTS = require('./desktop/ELECTRON_EVENTS'); /** * Electron main process that handles wrapping the web application. @@ -76,12 +77,18 @@ const mainWindow = (() => { app.on('before-quit', () => quitting = true); app.on('activate', () => browserWindow.show()); - ipcMain.on('request-visibility', (event) => { + ipcMain.on(ELECTRON_EVENTS.REQUEST_VISIBILITY, (event) => { // This is how synchronous messages work in Electron // eslint-disable-next-line no-param-reassign event.returnValue = browserWindow.isFocused(); }); + // Listen to badge updater event emitted by the render process + // and update the app badge count (MacOS only) + ipcMain.on(ELECTRON_EVENTS.REQUEST_UPDATE_BADGE_COUNT, (event, totalCount) => { + app.setBadgeCount(totalCount); + }); + return browserWindow; }) diff --git a/package-lock.json b/package-lock.json index 86c576a0efa99..edde568d61a01 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1822,6 +1822,14 @@ "resolved": "https://registry.npmjs.org/@react-native-community/netinfo/-/netinfo-5.9.6.tgz", "integrity": "sha512-cEkA1Apg8+VjnDdeDZRHI+2RqouiPKgYnewouRkvF4ettH9ZS4Cmi/nANQKIpIu2L+czboxM3fCZ44nc7IM9VQ==" }, + "@react-native-community/push-notification-ios": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@react-native-community/push-notification-ios/-/push-notification-ios-1.5.0.tgz", + "integrity": "sha512-88Uwu6S8oRVnuMfBMGN+MtTyUjiVmMKwfObYrPmm+b2E2Aqk0WlZ4clfECukG8QIzv1pfELJZ5uZMVTYMI6klg==", + "requires": { + "invariant": "^2.2.4" + } + }, "@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", diff --git a/package.json b/package.json index 1554ab43d2eae..43d062ac3e2c1 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "dependencies": { "@react-native-community/async-storage": "^1.11.0", "@react-native-community/netinfo": "^5.9.6", + "@react-native-community/push-notification-ios": "^1.5.0", "babel-plugin-transform-remove-console": "^6.9.4", "dotenv": "^8.2.0", "electron-context-menu": "^2.3.0", diff --git a/src/lib/PageTitleUpdater/index.native.js b/src/lib/PageTitleUpdater/index.native.js deleted file mode 100644 index e631e07e04bcc..0000000000000 --- a/src/lib/PageTitleUpdater/index.native.js +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Native devices (iOS, Android) don't have page title like web does, so this module doesn't do anything - */ -export default () => {}; diff --git a/src/lib/UnreadIndicatorUpdater/index.js b/src/lib/UnreadIndicatorUpdater/index.js new file mode 100644 index 0000000000000..6a461f804ab34 --- /dev/null +++ b/src/lib/UnreadIndicatorUpdater/index.js @@ -0,0 +1,52 @@ +import _ from 'underscore'; +import Ion from '../Ion'; +import IONKEYS from '../../IONKEYS'; +import updateUnread from './updateUnread'; + +// Stash the unread action counts for each report +const unreadActionCounts = {}; + +/** + * Updates the title and favicon of the current browser tab + * and Mac OS or iOS dock icon with an unread indicator. + */ +const throttledUpdatePageTitleAndUnreadCount = _.throttle(() => { + const totalCount = _.reduce(unreadActionCounts, (total, reportCount) => total + reportCount, 0); + updateUnread(totalCount); +}, 1000, {leading: false}); + +let connectionID; + +/** + * Bind to the report collection key and update + * the title and unread count indicators + */ +function listenForReportChanges() { + connectionID = Ion.connect({ + key: IONKEYS.COLLECTION.REPORT, + callback: (report) => { + if (!report || !report.reportID) { + return; + } + + unreadActionCounts[report.reportID] = report.unreadActionCount || 0; + throttledUpdatePageTitleAndUnreadCount(); + } + }); +} + +/** + * Remove the subscription callback when we no longer need it. + */ +function stopListeningForReportChanges() { + if (!connectionID) { + return; + } + + Ion.disconnect(connectionID); +} + +export default { + listenForReportChanges, + stopListeningForReportChanges, +}; diff --git a/src/lib/UnreadIndicatorUpdater/updateUnread/index.android.js b/src/lib/UnreadIndicatorUpdater/updateUnread/index.android.js new file mode 100644 index 0000000000000..731b8058a9a7b --- /dev/null +++ b/src/lib/UnreadIndicatorUpdater/updateUnread/index.android.js @@ -0,0 +1,2 @@ +// Android does not yet implement this +export default () => {}; diff --git a/src/lib/UnreadIndicatorUpdater/updateUnread/index.desktop.js b/src/lib/UnreadIndicatorUpdater/updateUnread/index.desktop.js new file mode 100644 index 0000000000000..34176ff9b7bd9 --- /dev/null +++ b/src/lib/UnreadIndicatorUpdater/updateUnread/index.desktop.js @@ -0,0 +1,16 @@ +import ELECTRON_EVENTS from '../../../../desktop/ELECTRON_EVENTS'; + +const ipcRenderer = window.require('electron').ipcRenderer; + +/** + * Set the badge on desktop + * + * @param {Number} totalCount + */ +function updateUnread(totalCount) { + // Ask the main Electron process to update our + // badge count in the Mac OS dock icon + ipcRenderer.send(ELECTRON_EVENTS.REQUEST_UPDATE_BADGE_COUNT, totalCount); +} + +export default updateUnread; diff --git a/src/lib/UnreadIndicatorUpdater/updateUnread/index.ios.js b/src/lib/UnreadIndicatorUpdater/updateUnread/index.ios.js new file mode 100644 index 0000000000000..1f9070be74f98 --- /dev/null +++ b/src/lib/UnreadIndicatorUpdater/updateUnread/index.ios.js @@ -0,0 +1,13 @@ +import PushNotificationIOS from '@react-native-community/push-notification-ios'; + +/** + * Set the App Icon badge with the number of + * unread messages on iOS + * + * @param {Number} totalCount + */ +function updateUnread(totalCount) { + PushNotificationIOS.setApplicationIconBadgeNumber(totalCount); +} + +export default updateUnread; diff --git a/src/lib/PageTitleUpdater/index.js b/src/lib/UnreadIndicatorUpdater/updateUnread/index.website.js similarity index 57% rename from src/lib/PageTitleUpdater/index.js rename to src/lib/UnreadIndicatorUpdater/updateUnread/index.website.js index 52bdd01d3944d..2f5c2769ed9f0 100644 --- a/src/lib/PageTitleUpdater/index.js +++ b/src/lib/UnreadIndicatorUpdater/updateUnread/index.website.js @@ -1,16 +1,17 @@ /** * Web browsers have a tab title and favicon which can be updated to show there are unread comments */ -import CONFIG from '../../CONFIG'; +import CONFIG from '../../../CONFIG'; /** - * Updates the title and favicon of the current browser tab with an unread indicator + * Set the page title on web * - * @param {boolean} hasUnread + * @param {Number} totalCount */ -const PageTitleUpdater = (hasUnread) => { +function updateUnread(totalCount) { + const hasUnread = totalCount > 0; document.title = hasUnread ? `(NEW!) ${CONFIG.SITE_TITLE}` : CONFIG.SITE_TITLE; document.getElementById('favicon').href = hasUnread ? CONFIG.FAVICON.UNREAD : CONFIG.FAVICON.DEFAULT; -}; +} -export default PageTitleUpdater; +export default updateUnread; diff --git a/src/lib/Visibility/index.js b/src/lib/Visibility/index.js index 7929d824a5f27..336d80bf17ea3 100644 --- a/src/lib/Visibility/index.js +++ b/src/lib/Visibility/index.js @@ -1,3 +1,5 @@ +import ELECTRON_EVENTS from '../../../desktop/ELECTRON_EVENTS'; + // We conditionally import the ipcRenderer here so that we can // communicate with the main Electron process in main.js const ipcRenderer = window.require ? window.require('electron').ipcRenderer : null; @@ -13,7 +15,7 @@ const ipcRenderer = window.require ? window.require('electron').ipcRenderer : nu */ function isVisible() { return ipcRenderer - ? ipcRenderer.sendSync('request-visibility') + ? ipcRenderer.sendSync(ELECTRON_EVENTS.REQUEST_VISIBILITY) : document.visibilityState === 'visible'; } diff --git a/src/lib/actions/SignInRedirect.js b/src/lib/actions/SignInRedirect.js index a81f0112f1766..973a6461014f3 100644 --- a/src/lib/actions/SignInRedirect.js +++ b/src/lib/actions/SignInRedirect.js @@ -4,6 +4,7 @@ import ROUTES from '../../ROUTES'; import {redirect} from './App'; import * as Pusher from '../Pusher/pusher'; import NetworkConnection from '../NetworkConnection'; +import UnreadIndicatorUpdater from '../UnreadIndicatorUpdater'; let currentURL; Ion.connect({ @@ -19,6 +20,7 @@ Ion.connect({ */ function redirectToSignIn(errorMessage) { NetworkConnection.stopListeningForReconnect(); + UnreadIndicatorUpdater.stopListeningForReportChanges(); Pusher.disconnect(); Ion.clear() .then(() => { diff --git a/src/page/home/HomePage.js b/src/page/home/HomePage.js index ffca8a76933a4..42547a3bae86a 100644 --- a/src/page/home/HomePage.js +++ b/src/page/home/HomePage.js @@ -15,6 +15,7 @@ import Main from './MainView'; import {subscribeToReportCommentEvents, fetchAll as fetchAllReports} from '../../lib/actions/Report'; import {fetch as fetchPersonalDetails} from '../../lib/actions/PersonalDetails'; import * as Pusher from '../../lib/Pusher/pusher'; +import UnreadIndicatorUpdater from '../../lib/UnreadIndicatorUpdater'; import ROUTES from '../../ROUTES'; import NetworkConnection from '../../lib/NetworkConnection'; @@ -47,6 +48,8 @@ export default class App extends React.Component { // Fetch all the reports fetchAllReports(); + UnreadIndicatorUpdater.listenForReportChanges(); + Dimensions.addEventListener('change', this.toggleHamburgerBasedOnDimensions); StatusBar.setBarStyle('dark-content', true); diff --git a/src/page/home/sidebar/SidebarLinks.js b/src/page/home/sidebar/SidebarLinks.js index b13d7fc90b538..6af6c4e519053 100644 --- a/src/page/home/sidebar/SidebarLinks.js +++ b/src/page/home/sidebar/SidebarLinks.js @@ -9,7 +9,6 @@ import SidebarLink from './SidebarLink'; import withIon from '../../../components/withIon'; import IONKEYS from '../../../IONKEYS'; import ChatSwitcherView from './ChatSwitcherView'; -import PageTitleUpdater from '../../../lib/PageTitleUpdater'; import SafeAreaInsetPropTypes from '../../SafeAreaInsetPropTypes'; import compose from '../../../lib/compose'; import {withRouter} from '../../../lib/Router'; @@ -62,9 +61,6 @@ class SidebarLinks extends React.Component { // eslint-disable-next-line max-len const reportsToDisplay = _.filter(sortedReports, report => (report.pinnedReport || (report.unreadActionCount > 0) || report.reportID === reportIDInUrl)); - // Updates the page title to indicate there are unread reports - PageTitleUpdater(_.any(sortedReports, report => report.unreadActionCount > 0)); - // Update styles to hide the report links if they should not be visible const sidebarLinksStyle = this.state.areReportLinksVisible ? [styles.sidebarListContainer]