@capgo/capacitor-realtimekit 7.0.5 → 7.1.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/Package.swift +4 -2
- package/android/src/main/java/ee/forgr/plugin/capacitor_realtimekit/CapacitorRealtimekitPlugin.java +93 -15
- package/ios/Sources/CapacitorRealtimekitPlugin/CapacitorRealtimekit.swift +70 -25
- package/ios/Sources/CapacitorRealtimekitPlugin/CapacitorRealtimekitPlugin.swift +9 -3
- package/package.json +1 -1
package/Package.swift
CHANGED
|
@@ -11,7 +11,8 @@ let package = Package(
|
|
|
11
11
|
],
|
|
12
12
|
dependencies: [
|
|
13
13
|
.package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "7.0.0"),
|
|
14
|
-
.package(url: "https://github.com/dyte-in/RealtimeKitCoreiOS.git", from: "1.0.0")
|
|
14
|
+
.package(url: "https://github.com/dyte-in/RealtimeKitCoreiOS.git", from: "1.0.0"),
|
|
15
|
+
.package(url: "https://github.com/dyte-in/RealtimeKitUI.git", from: "0.5.3")
|
|
15
16
|
],
|
|
16
17
|
targets: [
|
|
17
18
|
.target(
|
|
@@ -19,7 +20,8 @@ let package = Package(
|
|
|
19
20
|
dependencies: [
|
|
20
21
|
.product(name: "Capacitor", package: "capacitor-swift-pm"),
|
|
21
22
|
.product(name: "Cordova", package: "capacitor-swift-pm"),
|
|
22
|
-
.product(name: "RealtimeKit", package: "RealtimeKitCoreiOS")
|
|
23
|
+
.product(name: "RealtimeKit", package: "RealtimeKitCoreiOS"),
|
|
24
|
+
.product(name: "RealtimeKitUI", package: "RealtimeKitUI")
|
|
23
25
|
],
|
|
24
26
|
path: "ios/Sources/CapacitorRealtimekitPlugin"),
|
|
25
27
|
.testTarget(
|
package/android/src/main/java/ee/forgr/plugin/capacitor_realtimekit/CapacitorRealtimekitPlugin.java
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
package ee.forgr.plugin.capacitor_realtimekit;
|
|
2
2
|
|
|
3
3
|
import android.Manifest;
|
|
4
|
+
import android.app.Activity;
|
|
4
5
|
import android.util.Log;
|
|
6
|
+
import com.cloudflare.realtimekit.models.RtkMeetingInfo;
|
|
7
|
+
import com.cloudflare.realtimekit.ui.RealtimeKitUI;
|
|
8
|
+
import com.cloudflare.realtimekit.ui.RealtimeKitUIBuilder;
|
|
9
|
+
import com.cloudflare.realtimekit.ui.RealtimeKitUIInfo;
|
|
5
10
|
import com.getcapacitor.JSObject;
|
|
11
|
+
import com.getcapacitor.PermissionState;
|
|
6
12
|
import com.getcapacitor.Plugin;
|
|
7
13
|
import com.getcapacitor.PluginCall;
|
|
8
14
|
import com.getcapacitor.PluginMethod;
|
|
9
15
|
import com.getcapacitor.annotation.CapacitorPlugin;
|
|
10
16
|
import com.getcapacitor.annotation.Permission;
|
|
17
|
+
import com.getcapacitor.annotation.PermissionCallback;
|
|
11
18
|
|
|
12
19
|
@CapacitorPlugin(
|
|
13
20
|
name = "CapacitorRealtimekit",
|
|
@@ -19,8 +26,23 @@ import com.getcapacitor.annotation.Permission;
|
|
|
19
26
|
public class CapacitorRealtimekitPlugin extends Plugin {
|
|
20
27
|
|
|
21
28
|
private static final String TAG = "RealtimekitPlugin";
|
|
22
|
-
private final String
|
|
29
|
+
private static final String REALTIMEKIT_BASE_DOMAIN = "realtime.cloudflare.com";
|
|
30
|
+
private final String pluginVersion = "7.1.0";
|
|
23
31
|
private boolean isInitialized = false;
|
|
32
|
+
private PendingMeetingRequest pendingMeetingRequest;
|
|
33
|
+
|
|
34
|
+
private static final class PendingMeetingRequest {
|
|
35
|
+
|
|
36
|
+
private final String authToken;
|
|
37
|
+
private final boolean enableAudio;
|
|
38
|
+
private final boolean enableVideo;
|
|
39
|
+
|
|
40
|
+
private PendingMeetingRequest(String authToken, boolean enableAudio, boolean enableVideo) {
|
|
41
|
+
this.authToken = authToken;
|
|
42
|
+
this.enableAudio = enableAudio;
|
|
43
|
+
this.enableVideo = enableVideo;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
24
46
|
|
|
25
47
|
@Override
|
|
26
48
|
public void load() {
|
|
@@ -30,8 +52,6 @@ public class CapacitorRealtimekitPlugin extends Plugin {
|
|
|
30
52
|
|
|
31
53
|
@PluginMethod
|
|
32
54
|
public void initialize(PluginCall call) {
|
|
33
|
-
// Initialize the RealtimeKit SDK
|
|
34
|
-
// TODO: Add Cloudflare RealtimeKit SDK initialization here
|
|
35
55
|
isInitialized = true;
|
|
36
56
|
Log.d(TAG, "RealtimeKit initialized");
|
|
37
57
|
call.resolve();
|
|
@@ -53,20 +73,21 @@ public class CapacitorRealtimekitPlugin extends Plugin {
|
|
|
53
73
|
Boolean enableAudio = call.getBoolean("enableAudio", true);
|
|
54
74
|
Boolean enableVideo = call.getBoolean("enableVideo", true);
|
|
55
75
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
76
|
+
String trimmedToken = authToken.trim();
|
|
77
|
+
if (trimmedToken.isEmpty()) {
|
|
78
|
+
call.reject("authToken is required");
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
PendingMeetingRequest request = new PendingMeetingRequest(trimmedToken, enableAudio, enableVideo);
|
|
62
83
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
84
|
+
if (!hasMediaPermissions()) {
|
|
85
|
+
pendingMeetingRequest = request;
|
|
86
|
+
requestPermissionForAliases(new String[] { "camera", "microphone" }, call, "startMeetingPermissionsCallback");
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
66
89
|
|
|
67
|
-
|
|
68
|
-
// Real implementation would launch the meeting UI here
|
|
69
|
-
call.resolve();
|
|
90
|
+
launchMeeting(call, request);
|
|
70
91
|
}
|
|
71
92
|
|
|
72
93
|
@PluginMethod
|
|
@@ -79,4 +100,61 @@ public class CapacitorRealtimekitPlugin extends Plugin {
|
|
|
79
100
|
call.reject("Could not get plugin version", e);
|
|
80
101
|
}
|
|
81
102
|
}
|
|
103
|
+
|
|
104
|
+
@PermissionCallback
|
|
105
|
+
private void startMeetingPermissionsCallback(PluginCall call) {
|
|
106
|
+
if (call == null) {
|
|
107
|
+
pendingMeetingRequest = null;
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (!hasMediaPermissions()) {
|
|
112
|
+
pendingMeetingRequest = null;
|
|
113
|
+
call.reject("Camera and microphone permissions are required to start a meeting.");
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
PendingMeetingRequest request = pendingMeetingRequest;
|
|
118
|
+
pendingMeetingRequest = null;
|
|
119
|
+
|
|
120
|
+
if (request == null) {
|
|
121
|
+
call.reject("Missing meeting configuration after granting permissions.");
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
launchMeeting(call, request);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
private boolean hasMediaPermissions() {
|
|
129
|
+
return getPermissionState("camera") == PermissionState.GRANTED && getPermissionState("microphone") == PermissionState.GRANTED;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
private void launchMeeting(PluginCall call, PendingMeetingRequest request) {
|
|
133
|
+
pendingMeetingRequest = null;
|
|
134
|
+
Activity activity = getActivity();
|
|
135
|
+
if (activity == null) {
|
|
136
|
+
call.reject("Unable to access the current Activity to show the meeting UI.");
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
activity.runOnUiThread(() -> {
|
|
141
|
+
try {
|
|
142
|
+
RtkMeetingInfo meetingInfo = new RtkMeetingInfo(
|
|
143
|
+
request.authToken,
|
|
144
|
+
request.enableAudio,
|
|
145
|
+
request.enableVideo,
|
|
146
|
+
REALTIMEKIT_BASE_DOMAIN
|
|
147
|
+
);
|
|
148
|
+
RealtimeKitUIInfo uiInfo = new RealtimeKitUIInfo(activity, meetingInfo);
|
|
149
|
+
RealtimeKitUI realtimeKitUI = RealtimeKitUIBuilder.build(uiInfo);
|
|
150
|
+
RealtimeKitUIBuilder.getMeeting().setUiKitInfo("capacitor-android", pluginVersion);
|
|
151
|
+
realtimeKitUI.startMeeting();
|
|
152
|
+
Log.d(TAG, "RealtimeKit meeting started successfully");
|
|
153
|
+
call.resolve();
|
|
154
|
+
} catch (Exception e) {
|
|
155
|
+
Log.e(TAG, "Failed to start RealtimeKit meeting", e);
|
|
156
|
+
call.reject("Failed to start meeting: " + e.getMessage(), e);
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
}
|
|
82
160
|
}
|
|
@@ -1,12 +1,23 @@
|
|
|
1
|
+
import Capacitor
|
|
1
2
|
import Foundation
|
|
3
|
+
import RealtimeKit
|
|
4
|
+
import RealtimeKitUI
|
|
2
5
|
import UIKit
|
|
3
6
|
|
|
4
|
-
public class CapacitorRealtimekit: NSObject {
|
|
7
|
+
public final class CapacitorRealtimekit: NSObject {
|
|
8
|
+
private weak var plugin: CAPPlugin?
|
|
9
|
+
private let pluginVersion: String
|
|
10
|
+
private let baseDomain = "realtime.cloudflare.com"
|
|
5
11
|
private var isInitialized = false
|
|
12
|
+
private var realtimeKitUI: RealtimeKitUI?
|
|
13
|
+
|
|
14
|
+
init(plugin: CAPPlugin, pluginVersion: String) {
|
|
15
|
+
self.plugin = plugin
|
|
16
|
+
self.pluginVersion = pluginVersion
|
|
17
|
+
super.init()
|
|
18
|
+
}
|
|
6
19
|
|
|
7
20
|
public func initialize() {
|
|
8
|
-
// Initialize the RealtimeKit SDK
|
|
9
|
-
// TODO: Add Cloudflare RealtimeKit SDK initialization here
|
|
10
21
|
isInitialized = true
|
|
11
22
|
print("RealtimeKit initialized")
|
|
12
23
|
}
|
|
@@ -18,31 +29,65 @@ public class CapacitorRealtimekit: NSObject {
|
|
|
18
29
|
completion: @escaping (Error?) -> Void
|
|
19
30
|
) {
|
|
20
31
|
guard isInitialized else {
|
|
21
|
-
|
|
22
|
-
domain: "CapacitorRealtimekit",
|
|
23
|
-
code: -1,
|
|
24
|
-
userInfo: [NSLocalizedDescriptionKey: "RealtimeKit not initialized. Call initialize() first."]
|
|
25
|
-
)
|
|
26
|
-
completion(error)
|
|
32
|
+
completion(makeError("RealtimeKit not initialized. Call initialize() first."))
|
|
27
33
|
return
|
|
28
34
|
}
|
|
29
35
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
print("Starting meeting with authToken: \(authToken)")
|
|
40
|
-
print("Audio enabled: \(enableAudio)")
|
|
41
|
-
print("Video enabled: \(enableVideo)")
|
|
42
|
-
|
|
43
|
-
// For now, just complete successfully
|
|
44
|
-
// Real implementation would present the meeting UI here
|
|
45
|
-
completion(nil)
|
|
36
|
+
let trimmedToken = authToken.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
37
|
+
guard !trimmedToken.isEmpty else {
|
|
38
|
+
completion(makeError("authToken is required"))
|
|
39
|
+
return
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
guard let presenter = topViewController(from: plugin?.bridge?.viewController) else {
|
|
43
|
+
completion(makeError("Unable to find a view controller to present the meeting UI."))
|
|
44
|
+
return
|
|
46
45
|
}
|
|
46
|
+
|
|
47
|
+
DispatchQueue.main.async { [weak self] in
|
|
48
|
+
guard let self else { return }
|
|
49
|
+
|
|
50
|
+
let meetingInfo = RtkMeetingInfo(
|
|
51
|
+
authToken: trimmedToken,
|
|
52
|
+
enableAudio: enableAudio,
|
|
53
|
+
enableVideo: enableVideo,
|
|
54
|
+
baseDomain: self.baseDomain
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
let uiKit = RealtimeKitUI(meetingInfo: meetingInfo)
|
|
58
|
+
uiKit.rtkClient.setUiKitInfo(name: "capacitor-ios", version: self.pluginVersion)
|
|
59
|
+
self.realtimeKitUI = uiKit
|
|
60
|
+
|
|
61
|
+
let meetingController = uiKit.startMeeting { [weak self] in
|
|
62
|
+
self?.realtimeKitUI = nil
|
|
63
|
+
}
|
|
64
|
+
meetingController.modalPresentationStyle = .fullScreen
|
|
65
|
+
|
|
66
|
+
presenter.present(meetingController, animated: true) {
|
|
67
|
+
completion(nil)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
private func topViewController(from root: UIViewController?) -> UIViewController? {
|
|
73
|
+
guard let root else { return nil }
|
|
74
|
+
|
|
75
|
+
if let presented = root.presentedViewController {
|
|
76
|
+
return topViewController(from: presented)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if let navigation = root as? UINavigationController {
|
|
80
|
+
return topViewController(from: navigation.visibleViewController ?? navigation)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if let tab = root as? UITabBarController {
|
|
84
|
+
return topViewController(from: tab.selectedViewController ?? tab)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return root
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
private func makeError(_ message: String) -> NSError {
|
|
91
|
+
NSError(domain: "CapacitorRealtimekit", code: -1, userInfo: [NSLocalizedDescriptionKey: message])
|
|
47
92
|
}
|
|
48
93
|
}
|
|
@@ -7,7 +7,7 @@ import Capacitor
|
|
|
7
7
|
*/
|
|
8
8
|
@objc(CapacitorRealtimekitPlugin)
|
|
9
9
|
public class CapacitorRealtimekitPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
10
|
-
private let pluginVersion: String = "7.0
|
|
10
|
+
private let pluginVersion: String = "7.1.0"
|
|
11
11
|
public let identifier = "CapacitorRealtimekitPlugin"
|
|
12
12
|
public let jsName = "CapacitorRealtimekit"
|
|
13
13
|
public let pluginMethods: [CAPPluginMethod] = [
|
|
@@ -16,7 +16,7 @@ public class CapacitorRealtimekitPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
16
16
|
CAPPluginMethod(name: "getPluginVersion", returnType: CAPPluginReturnPromise)
|
|
17
17
|
]
|
|
18
18
|
|
|
19
|
-
private
|
|
19
|
+
private lazy var implementation = CapacitorRealtimekit(plugin: self, pluginVersion: pluginVersion)
|
|
20
20
|
|
|
21
21
|
@objc func initialize(_ call: CAPPluginCall) {
|
|
22
22
|
implementation.initialize()
|
|
@@ -29,11 +29,17 @@ public class CapacitorRealtimekitPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
29
29
|
return
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
let trimmedToken = authToken.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
33
|
+
if trimmedToken.isEmpty {
|
|
34
|
+
call.reject("authToken is required")
|
|
35
|
+
return
|
|
36
|
+
}
|
|
37
|
+
|
|
32
38
|
let enableAudio = call.getBool("enableAudio") ?? true
|
|
33
39
|
let enableVideo = call.getBool("enableVideo") ?? true
|
|
34
40
|
|
|
35
41
|
implementation.startMeeting(
|
|
36
|
-
authToken:
|
|
42
|
+
authToken: trimmedToken,
|
|
37
43
|
enableAudio: enableAudio,
|
|
38
44
|
enableVideo: enableVideo
|
|
39
45
|
) { error in
|
package/package.json
CHANGED