@developer_tribe/react-native-comnyx 0.14.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Comnyx.podspec +10 -2
- package/README.md +50 -0
- package/android/build.gradle +1 -0
- package/android/consumer-rules.pro +23 -0
- package/android/generated/java/com/comnyx/NativeComnyxSpec.java +46 -0
- package/android/generated/jni/RNComnyxSpec-generated.cpp +23 -1
- package/android/generated/jni/RNComnyxSpec.h +7 -0
- package/android/generated/jni/react/renderer/components/RNComnyxSpec/RNComnyxSpecJSI-generated.cpp +21 -0
- package/android/generated/jni/react/renderer/components/RNComnyxSpec/RNComnyxSpecJSI.h +70 -0
- package/android/src/main/AndroidManifest.xml +11 -1
- package/android/src/main/AndroidManifestNew.xml +11 -1
- package/android/src/main/java/com/comnyx/ComnyxMediaPickerModule.kt +105 -19
- package/android/src/main/java/com/comnyx/ComnyxModule.kt +7 -0
- package/android/src/main/java/com/comnyx/src/messaging/firebase/FirebaseMessagingService.kt +4 -6
- package/android/src/main/res/xml/comnyx_file_paths.xml +12 -0
- package/ios/APNService.swift +9 -9
- package/ios/Comnyx.swift +17 -8
- package/ios/ComnyxMediaPicker.m +6 -0
- package/ios/ComnyxMediaPicker.swift +106 -26
- package/ios/ComnyxMessaging.swift +2 -0
- package/ios/PrivacyInfo.xcprivacy +32 -0
- package/ios/comnyx_post_install.rb +25 -0
- package/ios/generated/RCTAppDependencyProvider.h +25 -0
- package/ios/generated/RCTAppDependencyProvider.mm +55 -0
- package/ios/generated/RCTModulesConformingToProtocolsProvider.h +18 -0
- package/ios/generated/RCTModulesConformingToProtocolsProvider.mm +33 -0
- package/ios/generated/RCTThirdPartyComponentsProvider.h +16 -0
- package/ios/generated/RCTThirdPartyComponentsProvider.mm +23 -0
- package/ios/generated/RNComnyxSpec/RNComnyxSpec-generated.mm +53 -0
- package/ios/generated/RNComnyxSpec/RNComnyxSpec.h +67 -0
- package/ios/generated/RNComnyxSpecJSI-generated.cpp +38 -0
- package/ios/generated/RNComnyxSpecJSI.h +89 -0
- package/ios/generated/ReactAppDependencyProvider.podspec +34 -0
- package/lib/commonjs/NativeComnyxMediaPicker.js +46 -6
- package/lib/commonjs/NativeComnyxMediaPicker.js.map +1 -1
- package/lib/commonjs/api/conversations.js +6 -6
- package/lib/commonjs/api/conversations.js.map +1 -1
- package/lib/commonjs/api/customers.js +3 -2
- package/lib/commonjs/api/customers.js.map +1 -1
- package/lib/commonjs/api/media.js +20 -6
- package/lib/commonjs/api/media.js.map +1 -1
- package/lib/commonjs/api/messages.js +3 -2
- package/lib/commonjs/api/messages.js.map +1 -1
- package/lib/commonjs/assets/gallery.png +0 -0
- package/lib/commonjs/assets/video-play.png +0 -0
- package/lib/commonjs/components/ChatList.js +93 -45
- package/lib/commonjs/components/ChatList.js.map +1 -1
- package/lib/commonjs/components/ComnyxErrorBoundary.js +92 -0
- package/lib/commonjs/components/ComnyxErrorBoundary.js.map +1 -0
- package/lib/commonjs/components/CustomerForm.js +2 -2
- package/lib/commonjs/components/CustomerForm.js.map +1 -1
- package/lib/commonjs/components/MediaMessageItem.js +4 -3
- package/lib/commonjs/components/MediaMessageItem.js.map +1 -1
- package/lib/commonjs/components/MediaPickerButton.js +211 -14
- package/lib/commonjs/components/MediaPickerButton.js.map +1 -1
- package/lib/commonjs/components/MediaViewerModal.js +7 -0
- package/lib/commonjs/components/MediaViewerModal.js.map +1 -1
- package/lib/commonjs/components/MessageInput.js +63 -13
- package/lib/commonjs/components/MessageInput.js.map +1 -1
- package/lib/commonjs/components/MessageItem.js +1 -2
- package/lib/commonjs/components/MessageItem.js.map +1 -1
- package/lib/commonjs/constants/translations.js +87 -116
- package/lib/commonjs/constants/translations.js.map +1 -1
- package/lib/commonjs/hooks/usePolling.js +25 -21
- package/lib/commonjs/hooks/usePolling.js.map +1 -1
- package/lib/commonjs/hooks/useThemeColors.js +12 -1
- package/lib/commonjs/hooks/useThemeColors.js.map +1 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/notifications/initializeNotifications.js +19 -16
- package/lib/commonjs/notifications/initializeNotifications.js.map +1 -1
- package/lib/commonjs/register/Accumulator.js +19 -6
- package/lib/commonjs/register/Accumulator.js.map +1 -1
- package/lib/commonjs/register/collectData.js +1 -1
- package/lib/commonjs/register/collectData.js.map +1 -1
- package/lib/commonjs/store/store.js +6 -0
- package/lib/commonjs/store/store.js.map +1 -1
- package/lib/commonjs/support/ComnyxSupport.js +60 -15
- package/lib/commonjs/support/ComnyxSupport.js.map +1 -1
- package/lib/commonjs/support/SupportConfigContext.js +24 -0
- package/lib/commonjs/support/SupportConfigContext.js.map +1 -0
- package/lib/commonjs/types/Theme.js +30 -2
- package/lib/commonjs/types/Theme.js.map +1 -1
- package/lib/commonjs/version.js +1 -1
- package/lib/module/NativeComnyxMediaPicker.js +43 -6
- package/lib/module/NativeComnyxMediaPicker.js.map +1 -1
- package/lib/module/api/conversations.js +6 -6
- package/lib/module/api/conversations.js.map +1 -1
- package/lib/module/api/customers.js +3 -2
- package/lib/module/api/customers.js.map +1 -1
- package/lib/module/api/media.js +21 -6
- package/lib/module/api/media.js.map +1 -1
- package/lib/module/api/messages.js +3 -2
- package/lib/module/api/messages.js.map +1 -1
- package/lib/module/assets/gallery.png +0 -0
- package/lib/module/assets/video-play.png +0 -0
- package/lib/module/components/ChatList.js +94 -46
- package/lib/module/components/ChatList.js.map +1 -1
- package/lib/module/components/ComnyxErrorBoundary.js +87 -0
- package/lib/module/components/ComnyxErrorBoundary.js.map +1 -0
- package/lib/module/components/CustomerForm.js +2 -2
- package/lib/module/components/CustomerForm.js.map +1 -1
- package/lib/module/components/MediaMessageItem.js +4 -3
- package/lib/module/components/MediaMessageItem.js.map +1 -1
- package/lib/module/components/MediaPickerButton.js +215 -18
- package/lib/module/components/MediaPickerButton.js.map +1 -1
- package/lib/module/components/MediaViewerModal.js +8 -1
- package/lib/module/components/MediaViewerModal.js.map +1 -1
- package/lib/module/components/MessageInput.js +64 -14
- package/lib/module/components/MessageInput.js.map +1 -1
- package/lib/module/components/MessageItem.js +1 -2
- package/lib/module/components/MessageItem.js.map +1 -1
- package/lib/module/constants/translations.js +87 -116
- package/lib/module/constants/translations.js.map +1 -1
- package/lib/module/hooks/usePolling.js +25 -21
- package/lib/module/hooks/usePolling.js.map +1 -1
- package/lib/module/hooks/useThemeColors.js +13 -2
- package/lib/module/hooks/useThemeColors.js.map +1 -1
- package/lib/module/index.js +0 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/notifications/initializeNotifications.js +19 -16
- package/lib/module/notifications/initializeNotifications.js.map +1 -1
- package/lib/module/register/Accumulator.js +19 -6
- package/lib/module/register/Accumulator.js.map +1 -1
- package/lib/module/register/collectData.js +1 -1
- package/lib/module/register/collectData.js.map +1 -1
- package/lib/module/store/store.js +6 -0
- package/lib/module/store/store.js.map +1 -1
- package/lib/module/support/ComnyxSupport.js +61 -16
- package/lib/module/support/ComnyxSupport.js.map +1 -1
- package/lib/module/support/SupportConfigContext.js +19 -0
- package/lib/module/support/SupportConfigContext.js.map +1 -0
- package/lib/module/types/Theme.js +30 -2
- package/lib/module/types/Theme.js.map +1 -1
- package/lib/module/version.js +1 -1
- package/lib/typescript/src/NativeComnyxMediaPicker.d.ts +11 -0
- package/lib/typescript/src/NativeComnyxMediaPicker.d.ts.map +1 -1
- package/lib/typescript/src/api/conversations.d.ts +2 -2
- package/lib/typescript/src/api/conversations.d.ts.map +1 -1
- package/lib/typescript/src/api/customers.d.ts +1 -1
- package/lib/typescript/src/api/customers.d.ts.map +1 -1
- package/lib/typescript/src/api/media.d.ts +3 -3
- package/lib/typescript/src/api/media.d.ts.map +1 -1
- package/lib/typescript/src/api/messages.d.ts +1 -1
- package/lib/typescript/src/api/messages.d.ts.map +1 -1
- package/lib/typescript/src/components/ChatList.d.ts.map +1 -1
- package/lib/typescript/src/components/ComnyxErrorBoundary.d.ts +18 -0
- package/lib/typescript/src/components/ComnyxErrorBoundary.d.ts.map +1 -0
- package/lib/typescript/src/components/MediaMessageItem.d.ts.map +1 -1
- package/lib/typescript/src/components/MediaPickerButton.d.ts.map +1 -1
- package/lib/typescript/src/components/MediaViewerModal.d.ts.map +1 -1
- package/lib/typescript/src/components/MessageInput.d.ts.map +1 -1
- package/lib/typescript/src/components/MessageItem.d.ts.map +1 -1
- package/lib/typescript/src/constants/translations.d.ts.map +1 -1
- package/lib/typescript/src/hooks/usePolling.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useThemeColors.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +2 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/notifications/initializeNotifications.d.ts.map +1 -1
- package/lib/typescript/src/register/Accumulator.d.ts.map +1 -1
- package/lib/typescript/src/register/collectData.d.ts +4 -1
- package/lib/typescript/src/register/collectData.d.ts.map +1 -1
- package/lib/typescript/src/store/store.d.ts +6 -2
- package/lib/typescript/src/store/store.d.ts.map +1 -1
- package/lib/typescript/src/support/ComnyxSupport.d.ts +56 -2
- package/lib/typescript/src/support/ComnyxSupport.d.ts.map +1 -1
- package/lib/typescript/src/support/SupportConfigContext.d.ts +58 -0
- package/lib/typescript/src/support/SupportConfigContext.d.ts.map +1 -0
- package/lib/typescript/src/support/index.d.ts +1 -0
- package/lib/typescript/src/support/index.d.ts.map +1 -1
- package/lib/typescript/src/types/Conversation.d.ts +2 -2
- package/lib/typescript/src/types/Conversation.d.ts.map +1 -1
- package/lib/typescript/src/types/Customer.d.ts +1 -1
- package/lib/typescript/src/types/Customer.d.ts.map +1 -1
- package/lib/typescript/src/types/LocalizationKeys.d.ts +0 -1
- package/lib/typescript/src/types/LocalizationKeys.d.ts.map +1 -1
- package/lib/typescript/src/types/MessageResponse.d.ts +7 -4
- package/lib/typescript/src/types/MessageResponse.d.ts.map +1 -1
- package/lib/typescript/src/types/Theme.d.ts +26 -0
- package/lib/typescript/src/types/Theme.d.ts.map +1 -1
- package/lib/typescript/src/version.d.ts +1 -1
- package/package.json +12 -25
- package/src/NativeComnyxMediaPicker.ts +46 -7
- package/src/api/conversations.ts +6 -4
- package/src/api/customers.ts +3 -1
- package/src/api/media.ts +32 -10
- package/src/api/messages.ts +3 -1
- package/src/assets/gallery.png +0 -0
- package/src/assets/video-play.png +0 -0
- package/src/components/ChatList.tsx +115 -55
- package/src/components/ComnyxErrorBoundary.tsx +91 -0
- package/src/components/CustomerForm.tsx +2 -2
- package/src/components/MediaMessageItem.tsx +10 -3
- package/src/components/MediaPickerButton.tsx +238 -17
- package/src/components/MediaViewerModal.tsx +8 -1
- package/src/components/MessageInput.tsx +89 -16
- package/src/components/MessageItem.tsx +12 -14
- package/src/constants/translations.ts +87 -116
- package/src/hooks/usePolling.ts +21 -11
- package/src/hooks/useThemeColors.ts +11 -2
- package/src/index.ts +12 -0
- package/src/notifications/initializeNotifications.ts +22 -20
- package/src/register/Accumulator.ts +26 -9
- package/src/register/collectData.ts +10 -2
- package/src/store/store.ts +11 -3
- package/src/support/ComnyxSupport.tsx +128 -22
- package/src/support/SupportConfigContext.tsx +79 -0
- package/src/support/index.ts +7 -0
- package/src/types/Conversation.ts +2 -2
- package/src/types/Customer.ts +1 -2
- package/src/types/LocalizationKeys.ts +0 -1
- package/src/types/MessageResponse.ts +4 -4
- package/src/types/Theme.ts +38 -0
- package/src/version.ts +1 -1
package/Comnyx.podspec
CHANGED
|
@@ -11,13 +11,21 @@ Pod::Spec.new do |s|
|
|
|
11
11
|
s.authors = package["author"]
|
|
12
12
|
s.swift_version = "5.9"
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
# Explicit minimum target. The podspec used to rely on
|
|
15
|
+
# `min_ios_version_supported`, which is only defined when React Native's
|
|
16
|
+
# cocoapods helpers are loaded. If a host builds with a different setup that
|
|
17
|
+
# helper is undefined and the podspec fails to parse.
|
|
18
|
+
s.platforms = { :ios => '14.0' }
|
|
15
19
|
s.source = { :git => "https://www.npmjs.com.git", :tag => "#{s.version}" }
|
|
16
20
|
|
|
17
21
|
s.source_files = "ios/**/*.{h,m,mm,cpp,swift}"
|
|
18
|
-
|
|
22
|
+
|
|
19
23
|
# Exclude generated files to avoid duplicate definitions
|
|
20
24
|
s.exclude_files = "ios/generated/**/*"
|
|
25
|
+
|
|
26
|
+
s.resource_bundles = {
|
|
27
|
+
'Comnyx_Privacy' => ['ios/PrivacyInfo.xcprivacy']
|
|
28
|
+
}
|
|
21
29
|
|
|
22
30
|
# Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0.
|
|
23
31
|
# See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79.
|
package/README.md
CHANGED
|
@@ -31,6 +31,37 @@ npx react-native run-android
|
|
|
31
31
|
|
|
32
32
|
**Note:** If you don't install `react-native-mmkv`, the SDK will use in-memory storage as a fallback. This means your data will not persist between app restarts.
|
|
33
33
|
|
|
34
|
+
### iOS Podfile (required for React Native 0.85+)
|
|
35
|
+
|
|
36
|
+
React Native 0.85 ships React-Core as a prebuilt XCFramework whose umbrella header is not compatible with Xcode 26's strict Clang explicit modules. Without the patch below, `pod install` succeeds but `xcodebuild` fails while compiling the React-Core umbrella.
|
|
37
|
+
|
|
38
|
+
Comnyx ships a helper that applies the required build setting to every pod target. Wire it into your `ios/Podfile`:
|
|
39
|
+
|
|
40
|
+
```ruby
|
|
41
|
+
require_relative '../node_modules/@developer_tribe/react-native-comnyx/ios/comnyx_post_install'
|
|
42
|
+
|
|
43
|
+
# ...
|
|
44
|
+
|
|
45
|
+
target 'YourApp' do
|
|
46
|
+
config = use_native_modules!
|
|
47
|
+
use_react_native!(:path => config[:reactNativePath], :app_path => "#{Pod::Config.instance.installation_root}/..")
|
|
48
|
+
|
|
49
|
+
post_install do |installer|
|
|
50
|
+
comnyx_post_install(installer)
|
|
51
|
+
|
|
52
|
+
react_native_post_install(installer, config[:reactNativePath], :mac_catalyst_enabled => false)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Then reinstall pods:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
cd ios && pod install && cd ..
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The helper is a no-op on React Native < 0.85, so it is safe to add before upgrading.
|
|
64
|
+
|
|
34
65
|
## Basic Setup (Required)
|
|
35
66
|
|
|
36
67
|
### 1. Initialization and Login
|
|
@@ -77,6 +108,25 @@ const SupportScreen = () => {
|
|
|
77
108
|
};
|
|
78
109
|
```
|
|
79
110
|
|
|
111
|
+
### 3. Media Attachments in Support (iOS Info.plist)
|
|
112
|
+
|
|
113
|
+
The support UI lets users attach images and videos. On Android the system
|
|
114
|
+
Photo Picker (Android 13+) or the document picker (older) handles this
|
|
115
|
+
permission-free. On iOS the SDK uses `PHPicker` on iOS 14+ (no permission
|
|
116
|
+
needed) and falls back to `UIImagePickerController` on iOS 13.
|
|
117
|
+
|
|
118
|
+
If you ship iOS 13 support, add the following to your host app's
|
|
119
|
+
`Info.plist` so the fallback works without crashing:
|
|
120
|
+
|
|
121
|
+
```xml
|
|
122
|
+
<key>NSPhotoLibraryUsageDescription</key>
|
|
123
|
+
<string>Needed to attach photos and videos to support conversations.</string>
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
If your deployment target is iOS 14+, this key is not strictly required but
|
|
127
|
+
App Store reviewers often expect it whenever `PHPickerViewController` is
|
|
128
|
+
linked.
|
|
129
|
+
|
|
80
130
|
## Push Notifications Setup (Optional)
|
|
81
131
|
|
|
82
132
|
### 1. Account Prerequisites
|
package/android/build.gradle
CHANGED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# ProGuard / R8 rules bundled with the Comnyx RN library. These are applied
|
|
2
|
+
# automatically by host apps when they consume the library's AAR.
|
|
3
|
+
|
|
4
|
+
# React Native bridge uses reflection to resolve @ReactMethod and the
|
|
5
|
+
# generated TurboModule spec. Keep the module, package, and codegen spec.
|
|
6
|
+
-keep class com.comnyx.ComnyxModule { *; }
|
|
7
|
+
-keep class com.comnyx.ComnyxMediaPickerModule { *; }
|
|
8
|
+
-keep class com.comnyx.ComnyxPackage { *; }
|
|
9
|
+
-keep class com.comnyx.NativeComnyxSpec { *; }
|
|
10
|
+
|
|
11
|
+
# Firebase messaging reflectively instantiates the overridden service and
|
|
12
|
+
# calls its lifecycle methods.
|
|
13
|
+
-keep class com.comnyx.messaging.ComnyxFirebaseMessagingService { *; }
|
|
14
|
+
|
|
15
|
+
# Keep the video player activity referenced from manifest by name.
|
|
16
|
+
-keep class com.comnyx.VideoPlayerActivity { *; }
|
|
17
|
+
|
|
18
|
+
# Methods reached via @ReactMethod annotations. The annotation itself is a
|
|
19
|
+
# runtime one; keep everything it marks.
|
|
20
|
+
-keep @com.facebook.react.bridge.ReactMethod class * { *; }
|
|
21
|
+
-keepclassmembers class * {
|
|
22
|
+
@com.facebook.react.bridge.ReactMethod <methods>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
|
|
4
|
+
*
|
|
5
|
+
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
|
6
|
+
* once the code is regenerated.
|
|
7
|
+
*
|
|
8
|
+
* @generated by codegen project: GenerateModuleJavaSpec.js
|
|
9
|
+
*
|
|
10
|
+
* @nolint
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
package com.comnyx;
|
|
14
|
+
|
|
15
|
+
import com.facebook.proguard.annotations.DoNotStrip;
|
|
16
|
+
import com.facebook.react.bridge.Promise;
|
|
17
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
18
|
+
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
|
19
|
+
import com.facebook.react.bridge.ReactMethod;
|
|
20
|
+
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
|
|
21
|
+
import javax.annotation.Nonnull;
|
|
22
|
+
|
|
23
|
+
public abstract class NativeComnyxSpec extends ReactContextBaseJavaModule implements TurboModule {
|
|
24
|
+
public static final String NAME = "Comnyx";
|
|
25
|
+
|
|
26
|
+
public NativeComnyxSpec(ReactApplicationContext reactContext) {
|
|
27
|
+
super(reactContext);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@Override
|
|
31
|
+
public @Nonnull String getName() {
|
|
32
|
+
return NAME;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@ReactMethod
|
|
36
|
+
@DoNotStrip
|
|
37
|
+
public abstract void initialize(Promise promise);
|
|
38
|
+
|
|
39
|
+
@ReactMethod
|
|
40
|
+
@DoNotStrip
|
|
41
|
+
public abstract void checkOptIn(Promise promise);
|
|
42
|
+
|
|
43
|
+
@ReactMethod
|
|
44
|
+
@DoNotStrip
|
|
45
|
+
public abstract void optIn(Promise promise);
|
|
46
|
+
}
|
|
@@ -12,10 +12,32 @@
|
|
|
12
12
|
|
|
13
13
|
namespace facebook::react {
|
|
14
14
|
|
|
15
|
+
static facebook::jsi::Value __hostFunction_NativeComnyxSpecJSI_initialize(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
|
16
|
+
static jmethodID cachedMethodId = nullptr;
|
|
17
|
+
return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, PromiseKind, "initialize", "(Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId);
|
|
18
|
+
}
|
|
15
19
|
|
|
20
|
+
static facebook::jsi::Value __hostFunction_NativeComnyxSpecJSI_checkOptIn(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
|
21
|
+
static jmethodID cachedMethodId = nullptr;
|
|
22
|
+
return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, PromiseKind, "checkOptIn", "(Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId);
|
|
23
|
+
}
|
|
16
24
|
|
|
17
|
-
|
|
25
|
+
static facebook::jsi::Value __hostFunction_NativeComnyxSpecJSI_optIn(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {
|
|
26
|
+
static jmethodID cachedMethodId = nullptr;
|
|
27
|
+
return static_cast<JavaTurboModule &>(turboModule).invokeJavaMethod(rt, PromiseKind, "optIn", "(Lcom/facebook/react/bridge/Promise;)V", args, count, cachedMethodId);
|
|
28
|
+
}
|
|
18
29
|
|
|
30
|
+
NativeComnyxSpecJSI::NativeComnyxSpecJSI(const JavaTurboModule::InitParams ¶ms)
|
|
31
|
+
: JavaTurboModule(params) {
|
|
32
|
+
methodMap_["initialize"] = MethodMetadata {0, __hostFunction_NativeComnyxSpecJSI_initialize};
|
|
33
|
+
methodMap_["checkOptIn"] = MethodMetadata {0, __hostFunction_NativeComnyxSpecJSI_checkOptIn};
|
|
34
|
+
methodMap_["optIn"] = MethodMetadata {0, __hostFunction_NativeComnyxSpecJSI_optIn};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
std::shared_ptr<TurboModule> RNComnyxSpec_ModuleProvider(const std::string &moduleName, const JavaTurboModule::InitParams ¶ms) {
|
|
38
|
+
if (moduleName == "Comnyx") {
|
|
39
|
+
return std::make_shared<NativeComnyxSpecJSI>(params);
|
|
40
|
+
}
|
|
19
41
|
return nullptr;
|
|
20
42
|
}
|
|
21
43
|
|
|
@@ -16,6 +16,13 @@
|
|
|
16
16
|
|
|
17
17
|
namespace facebook::react {
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* JNI C++ class for module 'NativeComnyx'
|
|
21
|
+
*/
|
|
22
|
+
class JSI_EXPORT NativeComnyxSpecJSI : public JavaTurboModule {
|
|
23
|
+
public:
|
|
24
|
+
NativeComnyxSpecJSI(const JavaTurboModule::InitParams ¶ms);
|
|
25
|
+
};
|
|
19
26
|
|
|
20
27
|
|
|
21
28
|
JSI_EXPORT
|
package/android/generated/jni/react/renderer/components/RNComnyxSpec/RNComnyxSpecJSI-generated.cpp
CHANGED
|
@@ -11,7 +11,28 @@
|
|
|
11
11
|
|
|
12
12
|
namespace facebook::react {
|
|
13
13
|
|
|
14
|
+
static jsi::Value __hostFunction_NativeComnyxCxxSpecJSI_initialize(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
|
|
15
|
+
return static_cast<NativeComnyxCxxSpecJSI *>(&turboModule)->initialize(
|
|
16
|
+
rt
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
static jsi::Value __hostFunction_NativeComnyxCxxSpecJSI_checkOptIn(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
|
|
20
|
+
return static_cast<NativeComnyxCxxSpecJSI *>(&turboModule)->checkOptIn(
|
|
21
|
+
rt
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
static jsi::Value __hostFunction_NativeComnyxCxxSpecJSI_optIn(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
|
|
25
|
+
return static_cast<NativeComnyxCxxSpecJSI *>(&turboModule)->optIn(
|
|
26
|
+
rt
|
|
27
|
+
);
|
|
28
|
+
}
|
|
14
29
|
|
|
30
|
+
NativeComnyxCxxSpecJSI::NativeComnyxCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker)
|
|
31
|
+
: TurboModule("Comnyx", jsInvoker) {
|
|
32
|
+
methodMap_["initialize"] = MethodMetadata {0, __hostFunction_NativeComnyxCxxSpecJSI_initialize};
|
|
33
|
+
methodMap_["checkOptIn"] = MethodMetadata {0, __hostFunction_NativeComnyxCxxSpecJSI_checkOptIn};
|
|
34
|
+
methodMap_["optIn"] = MethodMetadata {0, __hostFunction_NativeComnyxCxxSpecJSI_optIn};
|
|
35
|
+
}
|
|
15
36
|
|
|
16
37
|
|
|
17
38
|
} // namespace facebook::react
|
|
@@ -15,5 +15,75 @@
|
|
|
15
15
|
namespace facebook::react {
|
|
16
16
|
|
|
17
17
|
|
|
18
|
+
class JSI_EXPORT NativeComnyxCxxSpecJSI : public TurboModule {
|
|
19
|
+
protected:
|
|
20
|
+
NativeComnyxCxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker);
|
|
21
|
+
|
|
22
|
+
public:
|
|
23
|
+
virtual jsi::Value initialize(jsi::Runtime &rt) = 0;
|
|
24
|
+
virtual jsi::Value checkOptIn(jsi::Runtime &rt) = 0;
|
|
25
|
+
virtual jsi::Value optIn(jsi::Runtime &rt) = 0;
|
|
26
|
+
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
template <typename T>
|
|
30
|
+
class JSI_EXPORT NativeComnyxCxxSpec : public TurboModule {
|
|
31
|
+
public:
|
|
32
|
+
jsi::Value create(jsi::Runtime &rt, const jsi::PropNameID &propName) override {
|
|
33
|
+
return delegate_.create(rt, propName);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime& runtime) override {
|
|
37
|
+
return delegate_.getPropertyNames(runtime);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
static constexpr std::string_view kModuleName = "Comnyx";
|
|
41
|
+
|
|
42
|
+
protected:
|
|
43
|
+
NativeComnyxCxxSpec(std::shared_ptr<CallInvoker> jsInvoker)
|
|
44
|
+
: TurboModule(std::string{NativeComnyxCxxSpec::kModuleName}, jsInvoker),
|
|
45
|
+
delegate_(reinterpret_cast<T*>(this), jsInvoker) {}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
private:
|
|
49
|
+
class Delegate : public NativeComnyxCxxSpecJSI {
|
|
50
|
+
public:
|
|
51
|
+
Delegate(T *instance, std::shared_ptr<CallInvoker> jsInvoker) :
|
|
52
|
+
NativeComnyxCxxSpecJSI(std::move(jsInvoker)), instance_(instance) {
|
|
53
|
+
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
jsi::Value initialize(jsi::Runtime &rt) override {
|
|
57
|
+
static_assert(
|
|
58
|
+
bridging::getParameterCount(&T::initialize) == 1,
|
|
59
|
+
"Expected initialize(...) to have 1 parameters");
|
|
60
|
+
|
|
61
|
+
return bridging::callFromJs<jsi::Value>(
|
|
62
|
+
rt, &T::initialize, jsInvoker_, instance_);
|
|
63
|
+
}
|
|
64
|
+
jsi::Value checkOptIn(jsi::Runtime &rt) override {
|
|
65
|
+
static_assert(
|
|
66
|
+
bridging::getParameterCount(&T::checkOptIn) == 1,
|
|
67
|
+
"Expected checkOptIn(...) to have 1 parameters");
|
|
68
|
+
|
|
69
|
+
return bridging::callFromJs<jsi::Value>(
|
|
70
|
+
rt, &T::checkOptIn, jsInvoker_, instance_);
|
|
71
|
+
}
|
|
72
|
+
jsi::Value optIn(jsi::Runtime &rt) override {
|
|
73
|
+
static_assert(
|
|
74
|
+
bridging::getParameterCount(&T::optIn) == 1,
|
|
75
|
+
"Expected optIn(...) to have 1 parameters");
|
|
76
|
+
|
|
77
|
+
return bridging::callFromJs<jsi::Value>(
|
|
78
|
+
rt, &T::optIn, jsInvoker_, instance_);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
private:
|
|
82
|
+
friend class NativeComnyxCxxSpec;
|
|
83
|
+
T *instance_;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
Delegate delegate_;
|
|
87
|
+
};
|
|
18
88
|
|
|
19
89
|
} // namespace facebook::react
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<service
|
|
6
6
|
android:name="com.comnyx.messaging.ComnyxFirebaseMessagingService"
|
|
7
7
|
android:priority="-1500"
|
|
8
|
-
android:exported="
|
|
8
|
+
android:exported="false">
|
|
9
9
|
<intent-filter>
|
|
10
10
|
<action android:name="com.google.firebase.MESSAGING_EVENT" />
|
|
11
11
|
</intent-filter>
|
|
@@ -14,5 +14,15 @@
|
|
|
14
14
|
android:name="com.comnyx.VideoPlayerActivity"
|
|
15
15
|
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
|
|
16
16
|
android:exported="false" />
|
|
17
|
+
|
|
18
|
+
<provider
|
|
19
|
+
android:name="androidx.core.content.FileProvider"
|
|
20
|
+
android:authorities="${applicationId}.comnyx.fileprovider"
|
|
21
|
+
android:exported="false"
|
|
22
|
+
android:grantUriPermissions="true">
|
|
23
|
+
<meta-data
|
|
24
|
+
android:name="android.support.FILE_PROVIDER_PATHS"
|
|
25
|
+
android:resource="@xml/comnyx_file_paths" />
|
|
26
|
+
</provider>
|
|
17
27
|
</application>
|
|
18
28
|
</manifest>
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<service
|
|
4
4
|
android:name="com.comnyx.messaging.ComnyxFirebaseMessagingService"
|
|
5
5
|
android:priority="-1500"
|
|
6
|
-
android:exported="
|
|
6
|
+
android:exported="false">
|
|
7
7
|
<intent-filter>
|
|
8
8
|
<action android:name="com.google.firebase.MESSAGING_EVENT" />
|
|
9
9
|
</intent-filter>
|
|
@@ -12,5 +12,15 @@
|
|
|
12
12
|
android:name="com.comnyx.VideoPlayerActivity"
|
|
13
13
|
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
|
|
14
14
|
android:exported="false" />
|
|
15
|
+
|
|
16
|
+
<provider
|
|
17
|
+
android:name="androidx.core.content.FileProvider"
|
|
18
|
+
android:authorities="${applicationId}.comnyx.fileprovider"
|
|
19
|
+
android:exported="false"
|
|
20
|
+
android:grantUriPermissions="true">
|
|
21
|
+
<meta-data
|
|
22
|
+
android:name="android.support.FILE_PROVIDER_PATHS"
|
|
23
|
+
android:resource="@xml/comnyx_file_paths" />
|
|
24
|
+
</provider>
|
|
15
25
|
</application>
|
|
16
26
|
</manifest>
|
|
@@ -5,12 +5,13 @@ import android.content.Intent
|
|
|
5
5
|
import android.graphics.Bitmap
|
|
6
6
|
import android.graphics.BitmapFactory
|
|
7
7
|
import android.net.Uri
|
|
8
|
+
import android.os.Build
|
|
9
|
+
import android.provider.MediaStore
|
|
8
10
|
import android.provider.OpenableColumns
|
|
9
|
-
import
|
|
11
|
+
import androidx.core.content.FileProvider
|
|
10
12
|
import com.facebook.react.bridge.*
|
|
11
13
|
import java.io.File
|
|
12
14
|
import java.io.FileOutputStream
|
|
13
|
-
import java.io.InputStream
|
|
14
15
|
import android.media.MediaMetadataRetriever
|
|
15
16
|
|
|
16
17
|
class ComnyxMediaPickerModule(reactContext: ReactApplicationContext) :
|
|
@@ -19,39 +20,81 @@ class ComnyxMediaPickerModule(reactContext: ReactApplicationContext) :
|
|
|
19
20
|
companion object {
|
|
20
21
|
const val NAME = "ComnyxMediaPicker"
|
|
21
22
|
private const val REQUEST_MEDIA = 2003
|
|
23
|
+
private const val REQUEST_IMAGE = 2004
|
|
24
|
+
private const val REQUEST_VIDEO = 2005
|
|
22
25
|
private const val COMPRESS_THRESHOLD = 500 * 1024 // 500KB
|
|
23
26
|
private const val COMPRESS_QUALITY = 80
|
|
24
27
|
}
|
|
25
28
|
|
|
29
|
+
private enum class PickerFilter { IMAGE, VIDEO, ANY }
|
|
30
|
+
|
|
26
31
|
private var promise: Promise? = null
|
|
27
32
|
|
|
33
|
+
private fun rejectPendingPromise() {
|
|
34
|
+
promise?.reject("CANCELLED", "A new picker request was made before the previous one completed")
|
|
35
|
+
promise = null
|
|
36
|
+
}
|
|
37
|
+
|
|
28
38
|
init {
|
|
29
39
|
reactContext.addActivityEventListener(this)
|
|
30
40
|
}
|
|
31
41
|
|
|
32
42
|
override fun getName(): String = NAME
|
|
33
43
|
|
|
44
|
+
/**
|
|
45
|
+
* On Android 13+ use the system Photo Picker (MediaStore.ACTION_PICK_IMAGES)
|
|
46
|
+
* which needs no runtime permission and is the recommended Google flow.
|
|
47
|
+
* Fall back to ACTION_GET_CONTENT on older releases.
|
|
48
|
+
*/
|
|
49
|
+
private fun buildPickerIntent(filter: PickerFilter): Intent {
|
|
50
|
+
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
|
51
|
+
Intent(MediaStore.ACTION_PICK_IMAGES).apply {
|
|
52
|
+
when (filter) {
|
|
53
|
+
PickerFilter.IMAGE -> type = "image/*"
|
|
54
|
+
PickerFilter.VIDEO -> type = "video/*"
|
|
55
|
+
PickerFilter.ANY -> {
|
|
56
|
+
// No type set: picker shows both images and videos.
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, MediaStore.getPickImagesMaxLimit())
|
|
60
|
+
}
|
|
61
|
+
} else {
|
|
62
|
+
Intent(Intent.ACTION_GET_CONTENT).apply {
|
|
63
|
+
when (filter) {
|
|
64
|
+
PickerFilter.IMAGE -> type = "image/*"
|
|
65
|
+
PickerFilter.VIDEO -> type = "video/*"
|
|
66
|
+
PickerFilter.ANY -> {
|
|
67
|
+
type = "*/*"
|
|
68
|
+
putExtra(Intent.EXTRA_MIME_TYPES, arrayOf("image/*", "video/*"))
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
|
|
72
|
+
addCategory(Intent.CATEGORY_OPENABLE)
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
34
76
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
@ReactMethod
|
|
39
|
-
fun pickMedia(promise: Promise) {
|
|
77
|
+
private fun launchPicker(filter: PickerFilter, requestCode: Int, promise: Promise) {
|
|
78
|
+
rejectPendingPromise()
|
|
40
79
|
this.promise = promise
|
|
41
80
|
val activity = reactApplicationContext.currentActivity
|
|
42
81
|
if (activity == null) {
|
|
43
82
|
promise.reject("NO_ACTIVITY", "Activity is not available")
|
|
83
|
+
this.promise = null
|
|
44
84
|
return
|
|
45
85
|
}
|
|
46
|
-
|
|
47
|
-
type = "*/*"
|
|
48
|
-
putExtra(Intent.EXTRA_MIME_TYPES, arrayOf("image/*", "video/*"))
|
|
49
|
-
putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
|
|
50
|
-
addCategory(Intent.CATEGORY_OPENABLE)
|
|
51
|
-
}
|
|
52
|
-
activity.startActivityForResult(intent, REQUEST_MEDIA)
|
|
86
|
+
activity.startActivityForResult(buildPickerIntent(filter), requestCode)
|
|
53
87
|
}
|
|
54
88
|
|
|
89
|
+
@ReactMethod
|
|
90
|
+
fun pickMedia(promise: Promise) = launchPicker(PickerFilter.ANY, REQUEST_MEDIA, promise)
|
|
91
|
+
|
|
92
|
+
@ReactMethod
|
|
93
|
+
fun pickImage(promise: Promise) = launchPicker(PickerFilter.IMAGE, REQUEST_IMAGE, promise)
|
|
94
|
+
|
|
95
|
+
@ReactMethod
|
|
96
|
+
fun pickVideo(promise: Promise) = launchPicker(PickerFilter.VIDEO, REQUEST_VIDEO, promise)
|
|
97
|
+
|
|
55
98
|
// MARK: - Generate Thumbnail from Video URL
|
|
56
99
|
|
|
57
100
|
@ReactMethod
|
|
@@ -124,7 +167,7 @@ class ComnyxMediaPickerModule(reactContext: ReactApplicationContext) :
|
|
|
124
167
|
// MARK: - Activity Result
|
|
125
168
|
|
|
126
169
|
override fun onActivityResult(activity: Activity, requestCode: Int, resultCode: Int, data: Intent?) {
|
|
127
|
-
if (requestCode != REQUEST_MEDIA) return
|
|
170
|
+
if (requestCode != REQUEST_MEDIA && requestCode != REQUEST_IMAGE && requestCode != REQUEST_VIDEO) return
|
|
128
171
|
|
|
129
172
|
if (resultCode != Activity.RESULT_OK || data == null) {
|
|
130
173
|
promise?.resolve(null)
|
|
@@ -262,14 +305,37 @@ class ComnyxMediaPickerModule(reactContext: ReactApplicationContext) :
|
|
|
262
305
|
}
|
|
263
306
|
}
|
|
264
307
|
|
|
308
|
+
/**
|
|
309
|
+
* Returns a content:// URI for a cached media file, backed by the
|
|
310
|
+
* Comnyx FileProvider declared in AndroidManifest.xml. Use this whenever
|
|
311
|
+
* a URI is about to cross the process boundary (e.g. ACTION_VIEW,
|
|
312
|
+
* ACTION_SEND) — file:// URIs throw FileUriExposedException on
|
|
313
|
+
* Android 7+.
|
|
314
|
+
*/
|
|
315
|
+
@ReactMethod
|
|
316
|
+
fun getShareableUri(fileUri: String, promise: Promise) {
|
|
317
|
+
try {
|
|
318
|
+
val path = fileUri.removePrefix("file://")
|
|
319
|
+
val file = File(path)
|
|
320
|
+
if (!file.exists()) {
|
|
321
|
+
promise.reject("FILE_NOT_FOUND", "File does not exist: $path")
|
|
322
|
+
return
|
|
323
|
+
}
|
|
324
|
+
val authority = "${reactApplicationContext.packageName}.comnyx.fileprovider"
|
|
325
|
+
val uri = FileProvider.getUriForFile(reactApplicationContext, authority, file)
|
|
326
|
+
promise.resolve(uri.toString())
|
|
327
|
+
} catch (e: Exception) {
|
|
328
|
+
promise.reject("SHAREABLE_URI_ERROR", e.message, e)
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
265
332
|
@ReactMethod
|
|
266
333
|
fun deleteTempFile(uri: String, promise: Promise) {
|
|
267
334
|
Thread {
|
|
268
335
|
try {
|
|
269
|
-
val
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
file.delete()
|
|
336
|
+
val resolved = resolveCachePath(uri)
|
|
337
|
+
if (resolved != null && resolved.exists()) {
|
|
338
|
+
resolved.delete()
|
|
273
339
|
}
|
|
274
340
|
promise.resolve(null)
|
|
275
341
|
} catch (e: Exception) {
|
|
@@ -278,6 +344,26 @@ class ComnyxMediaPickerModule(reactContext: ReactApplicationContext) :
|
|
|
278
344
|
}.start()
|
|
279
345
|
}
|
|
280
346
|
|
|
347
|
+
/**
|
|
348
|
+
* Resolve either a file:// URI or a content:// URI served by this
|
|
349
|
+
* library's FileProvider back to a File inside the app's cache dir.
|
|
350
|
+
* Returns null for any URI that does not point into our cache.
|
|
351
|
+
*/
|
|
352
|
+
private fun resolveCachePath(uri: String): File? {
|
|
353
|
+
if (uri.startsWith("file://")) {
|
|
354
|
+
return File(uri.removePrefix("file://"))
|
|
355
|
+
}
|
|
356
|
+
if (uri.startsWith("content://")) {
|
|
357
|
+
val parsed = Uri.parse(uri)
|
|
358
|
+
val expectedAuthority =
|
|
359
|
+
"${reactApplicationContext.packageName}.comnyx.fileprovider"
|
|
360
|
+
if (parsed.authority != expectedAuthority) return null
|
|
361
|
+
val name = parsed.lastPathSegment ?: return null
|
|
362
|
+
return File(reactApplicationContext.cacheDir, name)
|
|
363
|
+
}
|
|
364
|
+
return null
|
|
365
|
+
}
|
|
366
|
+
|
|
281
367
|
@ReactMethod
|
|
282
368
|
fun cleanupTempFiles(promise: Promise) {
|
|
283
369
|
Thread {
|
|
@@ -196,6 +196,13 @@ class ComnyxModule(reactContext: ReactApplicationContext) :
|
|
|
196
196
|
return false
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
+
internal fun emitTokenInit(token: String) {
|
|
200
|
+
Logger.v("emitTokenInit forwarded", NAME)
|
|
201
|
+
val params = Arguments.createMap()
|
|
202
|
+
params.putString("token", token)
|
|
203
|
+
sendEvent(reactApplicationContext, "TOKEN_INIT", params)
|
|
204
|
+
}
|
|
205
|
+
|
|
199
206
|
fun onNotificationShown(params: WritableMap) {
|
|
200
207
|
Logger.v("onNotificationShown event forwarded", NAME)
|
|
201
208
|
sendEvent(reactApplicationContext, "NOTIFICATION_RECEIVED", params)
|
|
@@ -36,12 +36,10 @@ open class ComnyxFirebaseMessagingService : FirebaseMessagingService() {
|
|
|
36
36
|
|
|
37
37
|
override fun onNewToken(token: String) {
|
|
38
38
|
Logger.v("onNewToken received", "Comnyx")
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
//TODO: send token to server
|
|
44
|
-
Logger.i("sendRegistrationTokenToServer called", "Comnyx")
|
|
39
|
+
// Forward refreshed token to JS via TOKEN_INIT; JS layer forwards to backend.
|
|
40
|
+
// If the module isn't attached yet (e.g. app not foregrounded), JS will fetch
|
|
41
|
+
// the current token via initialize() when it wakes up.
|
|
42
|
+
ComnyxModule.__self?.emitTokenInit(token)
|
|
45
43
|
}
|
|
46
44
|
|
|
47
45
|
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<!--
|
|
3
|
+
Paths exposed by the Comnyx FileProvider. The picker writes image/video
|
|
4
|
+
temp files to Context.cacheDir; expose that directory so host apps can
|
|
5
|
+
safely obtain content:// URIs (e.g. for ACTION_VIEW / ACTION_SEND on
|
|
6
|
+
Android 7+ where file:// URIs throw FileUriExposedException).
|
|
7
|
+
-->
|
|
8
|
+
<paths>
|
|
9
|
+
<cache-path
|
|
10
|
+
name="comnyx_cache"
|
|
11
|
+
path="." />
|
|
12
|
+
</paths>
|
package/ios/APNService.swift
CHANGED
|
@@ -26,25 +26,25 @@ class APNService {
|
|
|
26
26
|
|
|
27
27
|
func setAPNTokenListener(completion: @escaping (String, String?) -> Void) {
|
|
28
28
|
self.tokenCompletion = completion
|
|
29
|
-
if
|
|
30
|
-
completion("cache",
|
|
29
|
+
if let cachedToken = self.token {
|
|
30
|
+
completion("cache", cachedToken)
|
|
31
31
|
}
|
|
32
|
-
|
|
33
|
-
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted,
|
|
34
|
-
guard granted else {
|
|
32
|
+
|
|
33
|
+
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { [weak self] granted, _ in
|
|
34
|
+
guard granted, let self = self else {
|
|
35
35
|
return
|
|
36
36
|
}
|
|
37
|
-
|
|
38
|
-
DispatchQueue.main.async {
|
|
37
|
+
|
|
38
|
+
DispatchQueue.main.async { [weak self] in
|
|
39
|
+
guard let self = self else { return }
|
|
39
40
|
UIApplication.shared.registerForRemoteNotifications()
|
|
40
|
-
// Register for token notifications
|
|
41
41
|
NotificationCenter.default.addObserver(
|
|
42
42
|
self,
|
|
43
43
|
selector: #selector(self.didRegisterForRemoteNotifications),
|
|
44
44
|
name: NSNotification.Name("RCTRemoteNotificationRegistered"),
|
|
45
45
|
object: nil
|
|
46
46
|
)
|
|
47
|
-
|
|
47
|
+
|
|
48
48
|
NotificationCenter.default.addObserver(
|
|
49
49
|
self,
|
|
50
50
|
selector: #selector(self.didFailToRegisterForRemoteNotifications),
|