capacitor-plugin-vonage 0.0.1
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/CapacitorPluginVonage.podspec +20 -0
- package/README.md +126 -0
- package/android/build.gradle +76 -0
- package/android/src/main/AndroidManifest.xml +6 -0
- package/android/src/main/java/com/managemyhealth/plugin/vonage/VideoCallActivity.java +434 -0
- package/android/src/main/java/com/managemyhealth/plugin/vonage/vonage.java +11 -0
- package/android/src/main/java/com/managemyhealth/plugin/vonage/vonagePlugin.java +125 -0
- package/android/src/main/res/.gitkeep +0 -0
- package/android/src/main/res/drawable/callend.png +0 -0
- package/android/src/main/res/drawable/callstart.png +0 -0
- package/android/src/main/res/drawable/cameraoff.png +0 -0
- package/android/src/main/res/drawable/cameraonwhite.png +0 -0
- package/android/src/main/res/drawable/cameraswitch.png +0 -0
- package/android/src/main/res/drawable/ic_launcher_background.xml +170 -0
- package/android/src/main/res/drawable/microphoneoff.png +0 -0
- package/android/src/main/res/drawable/microphoneonwhite.png +0 -0
- package/android/src/main/res/layout/activity_main.xml +36 -0
- package/android/src/main/res/layout/video_call_layout.xml +282 -0
- package/android/src/main/res.zip +0 -0
- package/dist/docs.json +370 -0
- package/dist/esm/definitions.d.ts +12 -0
- package/dist/esm/definitions.js +2 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web.d.ts +12 -0
- package/dist/esm/web.js +13 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +29 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +32 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Plugin/Info.plist +24 -0
- package/ios/Plugin/VideoChatViewController.swift +387 -0
- package/ios/Plugin/vonage.swift +8 -0
- package/ios/Plugin/vonagePlugin.h +10 -0
- package/ios/Plugin/vonagePlugin.m +9 -0
- package/ios/Plugin/vonagePlugin.swift +80 -0
- package/package.json +78 -0
@@ -0,0 +1,387 @@
|
|
1
|
+
//
|
2
|
+
// VideoChatViewController.swift
|
3
|
+
// App
|
4
|
+
//
|
5
|
+
// Created by inlusr1 on 09/10/23.
|
6
|
+
//
|
7
|
+
|
8
|
+
import UIKit
|
9
|
+
import OpenTok
|
10
|
+
|
11
|
+
class VideoChatViewController: UIViewController,OTSessionDelegate,OTPublisherDelegate,OTSubscriberDelegate {
|
12
|
+
var kApiKey = ""
|
13
|
+
var kSessionId = ""
|
14
|
+
var kToken = ""
|
15
|
+
var publisherName = ""
|
16
|
+
var subscriberName = ""
|
17
|
+
var isProvider = false
|
18
|
+
var strCallerID : String?
|
19
|
+
var isAudioMute = false
|
20
|
+
var isSpeakerEnabled = true
|
21
|
+
var isVideoMute = false
|
22
|
+
var isBackCameraFace = false
|
23
|
+
var isCallInProgress = false
|
24
|
+
|
25
|
+
var videoCallParam = String()
|
26
|
+
|
27
|
+
var session: OTSession?
|
28
|
+
var publisher: OTPublisher?
|
29
|
+
var subscriber: OTSubscriber?
|
30
|
+
|
31
|
+
var remoteView = UIView()
|
32
|
+
var localView = UIView()
|
33
|
+
var camaraBtn = UIButton()
|
34
|
+
var videoBtn = UIButton()
|
35
|
+
var audioBtn = UIButton()
|
36
|
+
var callBtn = UIButton()
|
37
|
+
var publisherLabel = UILabel()
|
38
|
+
var subscriberLabel = UILabel()
|
39
|
+
var timerLabel = UILabel()
|
40
|
+
var counter = 0
|
41
|
+
var timer = Timer()
|
42
|
+
override func viewDidLoad() {
|
43
|
+
super.viewDidLoad()
|
44
|
+
self.navigationController?.navigationBar.isHidden = true
|
45
|
+
self.viewSetupMethod()
|
46
|
+
// let jsonParam = videoCallParam.toJSON() as? [String:AnyObject] // can be any type here
|
47
|
+
// print(jsonParam as Any)
|
48
|
+
|
49
|
+
// kApiKey = jsonParam?["apiKey"] as! String
|
50
|
+
// kSessionId = jsonParam?["sessionId"] as! String
|
51
|
+
// kToken = jsonParam?["token"] as! String
|
52
|
+
|
53
|
+
// DispatchQueue.main.async(execute: {
|
54
|
+
// self.connectToAnOpenTokSession()
|
55
|
+
// })
|
56
|
+
// DispatchQueue.main.asyncAfter(deadline: .now() + 2.0, execute: {
|
57
|
+
// var err: Error? = nil
|
58
|
+
// let session = AVAudioSession.sharedInstance()
|
59
|
+
// do {
|
60
|
+
// try session.setCategory(AVAudioSession.Category.playAndRecord, mode: .voiceChat, options: [.allowBluetooth, .allowBluetoothA2DP, .mixWithOthers])
|
61
|
+
// } catch {
|
62
|
+
// NSLog("Unable to change audio category because : \(String(describing: err?.localizedDescription))")
|
63
|
+
// err = nil
|
64
|
+
// }
|
65
|
+
//
|
66
|
+
// try? session.setMode(AVAudioSession.Mode.voiceChat)
|
67
|
+
// if err != nil {
|
68
|
+
// NSLog("Unable to change audio mode because : \(String(describing: err?.localizedDescription))")
|
69
|
+
// err = nil
|
70
|
+
// }
|
71
|
+
// let sampleRate: Double = 44100.0
|
72
|
+
// try? session.setPreferredSampleRate(sampleRate)
|
73
|
+
// if err != nil {
|
74
|
+
// NSLog("Unable to change preferred sample rate because : \(String(describing: err?.localizedDescription))")
|
75
|
+
// err = nil
|
76
|
+
// }
|
77
|
+
// try? session.setPreferredIOBufferDuration(0.005)
|
78
|
+
// if err != nil {
|
79
|
+
// NSLog("Unable to change preferred sample rate because : \(String(describing: err?.localizedDescription))")
|
80
|
+
// err = nil
|
81
|
+
// }
|
82
|
+
self.connectToAnOpenTokSession()
|
83
|
+
// })
|
84
|
+
}
|
85
|
+
override func viewDidAppear(_ animated: Bool) {
|
86
|
+
super.viewDidAppear(animated)
|
87
|
+
// DispatchQueue.main.asyncAfter(deadline: .now() + 1.0, execute: {
|
88
|
+
//
|
89
|
+
// self.connectToAnOpenTokSession()
|
90
|
+
// })
|
91
|
+
}
|
92
|
+
func startTimer(){
|
93
|
+
timer.invalidate()
|
94
|
+
timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true)
|
95
|
+
}
|
96
|
+
func stopTimer(){
|
97
|
+
timer.invalidate()
|
98
|
+
counter = 0
|
99
|
+
}
|
100
|
+
@objc func timerAction() {
|
101
|
+
counter += 1
|
102
|
+
timerLabel.text = stringFromTimeInterval(counter)
|
103
|
+
}
|
104
|
+
func stringFromTimeInterval(_ counter:Int) -> String {
|
105
|
+
|
106
|
+
let time = NSInteger(counter)
|
107
|
+
let seconds = time % 60
|
108
|
+
let minutes = (time / 60) % 60
|
109
|
+
let hours = (time / 3600)
|
110
|
+
|
111
|
+
return String(format: "%0.2d:%0.2d:%0.2d",hours,minutes,seconds)
|
112
|
+
|
113
|
+
}
|
114
|
+
func dynamicFontSize(_ FontSize: CGFloat) -> CGFloat {
|
115
|
+
let screenWidth = UIScreen.main.bounds.size.width
|
116
|
+
let calculatedFontSize = screenWidth / 375 * FontSize
|
117
|
+
return calculatedFontSize
|
118
|
+
}
|
119
|
+
func viewSetupMethod() {
|
120
|
+
let screenHeight = self.view.frame.height
|
121
|
+
let screenWidth = self.view.frame.width
|
122
|
+
|
123
|
+
remoteView = UIView(frame: CGRect(x: 0, y: 0, width: screenWidth, height:screenHeight))
|
124
|
+
remoteView.backgroundColor = UIColor(red: 83/255, green: 83/255, blue: 83/255, alpha: 1.0)
|
125
|
+
|
126
|
+
subscriberLabel = UILabel(frame: CGRect(x: 20, y: Int(screenHeight) - 180, width: Int(remoteView.frame.size.width - 140), height: 40))
|
127
|
+
subscriberLabel.text = subscriberName
|
128
|
+
//subscriberLabel.backgroundColor = UIColor(red: 31/255, green: 33/255, blue: 36/255, alpha: 1.0)
|
129
|
+
subscriberLabel.textColor = .white
|
130
|
+
subscriberLabel.textAlignment = .left
|
131
|
+
subscriberLabel.font = subscriberLabel.font.withSize(dynamicFontSize(15))
|
132
|
+
subscriberLabel.layer.zPosition = 1;
|
133
|
+
|
134
|
+
timerLabel = UILabel(frame: CGRect(x: 30, y: Int(screenHeight) - 155, width: Int(remoteView.frame.size.width - 140), height: 40))
|
135
|
+
//timerLabel.text = "00:00:00"
|
136
|
+
//subscriberLabel.backgroundColor = UIColor(red: 31/255, green: 33/255, blue: 36/255, alpha: 1.0)
|
137
|
+
timerLabel.textColor = .white
|
138
|
+
timerLabel.textAlignment = .left
|
139
|
+
timerLabel.font = subscriberLabel.font.withSize(dynamicFontSize(15))
|
140
|
+
timerLabel.layer.zPosition = 1;
|
141
|
+
|
142
|
+
remoteView.addSubview(timerLabel)
|
143
|
+
remoteView.addSubview(subscriberLabel)
|
144
|
+
self.view.addSubview(remoteView)
|
145
|
+
|
146
|
+
let bottomView = UIView(frame: CGRect(x: 0, y: screenHeight - 90, width: 320, height: 90))
|
147
|
+
bottomView.backgroundColor = UIColor.clear
|
148
|
+
bottomView.center = CGPoint(x: self.view.frame.size.width / 2, y: self.view.frame.size.height - 50)
|
149
|
+
|
150
|
+
self.view.addSubview(bottomView)
|
151
|
+
|
152
|
+
localView = UIView(frame: CGRect(x: screenWidth - 140, y: screenHeight - 250, width: 120, height: 120))
|
153
|
+
localView.backgroundColor = UIColor(red: 31/255, green: 33/255, blue: 36/255, alpha: 1.0)
|
154
|
+
|
155
|
+
localView.layer.cornerRadius = 10;
|
156
|
+
localView.clipsToBounds = true
|
157
|
+
|
158
|
+
publisherLabel = UILabel(frame: CGRect(x: 0, y: Int(localView.frame.size.height - 40.0), width: Int(localView.frame.size.width), height: 40))
|
159
|
+
publisherLabel.text = publisherName
|
160
|
+
// publisherLabel.backgroundColor = UIColor(red: 31/255, green: 33/255, blue: 36/255, alpha: 1.0)
|
161
|
+
publisherLabel.textColor = .white
|
162
|
+
publisherLabel.textAlignment = .center
|
163
|
+
publisherLabel.layer.zPosition = 1;
|
164
|
+
publisherLabel.font = publisherLabel.font.withSize(dynamicFontSize(15))
|
165
|
+
localView.addSubview(publisherLabel)
|
166
|
+
self.view.addSubview(localView)
|
167
|
+
|
168
|
+
callBtn = UIButton(frame: CGRect(x: 0, y: 0, width: 60, height: 60))
|
169
|
+
callBtn.backgroundColor = .clear
|
170
|
+
callBtn.setBackgroundImage(UIImage(named: "callEnd"), for: .normal)
|
171
|
+
callBtn.addTarget(self, action:#selector(self.callBtnbuttonClicked), for: .touchUpInside)
|
172
|
+
bottomView.addSubview(callBtn)
|
173
|
+
|
174
|
+
camaraBtn = UIButton(frame: CGRect(x: 80, y: 0, width: 60, height: 60))
|
175
|
+
camaraBtn.backgroundColor = .clear
|
176
|
+
camaraBtn.setBackgroundImage(UIImage(named: "cameraSwitch"), for: .normal)
|
177
|
+
camaraBtn.addTarget(self, action:#selector(self.camaraBtnbuttonClicked), for: .touchUpInside)
|
178
|
+
bottomView.addSubview(camaraBtn)
|
179
|
+
|
180
|
+
videoBtn = UIButton(frame: CGRect(x: 160, y: 0, width: 60, height: 60))
|
181
|
+
videoBtn.backgroundColor = .clear
|
182
|
+
videoBtn.setBackgroundImage(UIImage(named: "cameraOnWhite"), for: .normal)
|
183
|
+
videoBtn.addTarget(self, action:#selector(self.videoBtnbuttonClicked), for: .touchUpInside)
|
184
|
+
bottomView.addSubview(videoBtn)
|
185
|
+
|
186
|
+
audioBtn = UIButton(frame: CGRect(x: 240, y: 0, width: 60, height: 60))
|
187
|
+
audioBtn.backgroundColor = .clear
|
188
|
+
audioBtn.setBackgroundImage(UIImage(named: "microphoneOnWhite"), for: .normal)
|
189
|
+
audioBtn.addTarget(self, action:#selector(self.audioBtnbuttonClicked), for: .touchUpInside)
|
190
|
+
bottomView.addSubview(audioBtn)
|
191
|
+
|
192
|
+
}
|
193
|
+
|
194
|
+
@objc func callBtnbuttonClicked() {
|
195
|
+
|
196
|
+
let userInfo = ["userInfo": ["isProvider": isProvider]]
|
197
|
+
NotificationCenter.default.post(name: NSNotification.Name(NotificationNames.videoEnded),object: nil,userInfo: userInfo)
|
198
|
+
self.session?.disconnect(nil)
|
199
|
+
self.stopTimer()
|
200
|
+
self.dismiss(animated: true, completion: nil)
|
201
|
+
}
|
202
|
+
|
203
|
+
@objc func camaraBtnbuttonClicked() {
|
204
|
+
print("A stream was destroyed in the session.")
|
205
|
+
if (self.isBackCameraFace) {
|
206
|
+
print("A stream was destroyed in the session.1")
|
207
|
+
self.publisher?.cameraPosition = .front
|
208
|
+
self.isBackCameraFace = false
|
209
|
+
} else {
|
210
|
+
print("A stream was destroyed in the session.2")
|
211
|
+
self.publisher?.cameraPosition = .back
|
212
|
+
self.isBackCameraFace = true
|
213
|
+
}
|
214
|
+
}
|
215
|
+
|
216
|
+
@objc func videoBtnbuttonClicked() {
|
217
|
+
if (self.isVideoMute) {
|
218
|
+
self.publisher?.publishVideo = true
|
219
|
+
self.videoBtn.setImage(UIImage(named : "cameraOnWhite"), for: .normal)
|
220
|
+
self.isVideoMute = false
|
221
|
+
} else {
|
222
|
+
self.publisher?.publishVideo = false
|
223
|
+
self.videoBtn.setImage(UIImage(named:"cameraOff"), for: .normal)
|
224
|
+
self.isVideoMute = true
|
225
|
+
}
|
226
|
+
}
|
227
|
+
|
228
|
+
@objc func audioBtnbuttonClicked() {
|
229
|
+
if (self.isAudioMute) {
|
230
|
+
|
231
|
+
self.publisher?.publishAudio = true
|
232
|
+
self.audioBtn.setImage(UIImage(named : "microphoneOnWhite"), for: .normal)
|
233
|
+
self.isAudioMute = false
|
234
|
+
} else {
|
235
|
+
self.publisher?.publishAudio = false
|
236
|
+
self.audioBtn.setImage(UIImage(named:"microphoneOff"), for: .normal)
|
237
|
+
self.isAudioMute = true
|
238
|
+
}
|
239
|
+
}
|
240
|
+
|
241
|
+
func connectToAnOpenTokSession() {
|
242
|
+
session = OTSession(apiKey: kApiKey, sessionId: kSessionId, delegate: self)
|
243
|
+
//self.session = session
|
244
|
+
var error: OTError?
|
245
|
+
session?.connect(withToken: kToken, error: &error)
|
246
|
+
if error != nil {
|
247
|
+
print(error!)
|
248
|
+
}
|
249
|
+
}
|
250
|
+
|
251
|
+
//session methods
|
252
|
+
func sessionDidConnect(_ session: OTSession) {
|
253
|
+
print("The client connected to the OpenTok session.")
|
254
|
+
let userInfo = ["userInfo": ["isProvider": isProvider]]
|
255
|
+
NotificationCenter.default.post(name: NSNotification.Name(NotificationNames.videoStarted),object: nil,userInfo: userInfo)
|
256
|
+
let settings = OTPublisherSettings()
|
257
|
+
settings.name = publisherName
|
258
|
+
guard let publisher = OTPublisher(delegate: self, settings: settings) else {
|
259
|
+
return
|
260
|
+
}
|
261
|
+
self.publisher = publisher
|
262
|
+
var error: OTError?
|
263
|
+
session.publish(publisher, error: &error)
|
264
|
+
guard error == nil else {
|
265
|
+
print(error!)
|
266
|
+
return
|
267
|
+
}
|
268
|
+
|
269
|
+
guard let publisherView = publisher.view else {
|
270
|
+
return
|
271
|
+
}
|
272
|
+
|
273
|
+
// let screenBounds = UIScreen.main.bounds
|
274
|
+
//changed
|
275
|
+
publisherView.frame = CGRect(x: 0, y: 0 , width: localView.frame.width, height: localView.frame.height)
|
276
|
+
|
277
|
+
localView.addSubview(publisherView)
|
278
|
+
startTimer()
|
279
|
+
}
|
280
|
+
|
281
|
+
func sessionDidDisconnect(_ session: OTSession) {
|
282
|
+
print("The client disconnected from the OpenTok session.")
|
283
|
+
// self.session?.disconnect(nil)
|
284
|
+
self.dismiss(animated: true, completion: nil)
|
285
|
+
}
|
286
|
+
|
287
|
+
func session(_ session: OTSession, didFailWithError error: OTError) {
|
288
|
+
print("The client failed to connect to the OpenTok session: \(error).")
|
289
|
+
}
|
290
|
+
|
291
|
+
func session(_ session: OTSession, streamCreated stream: OTStream) {
|
292
|
+
subscriber = OTSubscriber(stream: stream, delegate: self)
|
293
|
+
guard let subscriber = subscriber else {
|
294
|
+
return
|
295
|
+
}
|
296
|
+
|
297
|
+
self.subscriber = subscriber
|
298
|
+
var error: OTError?
|
299
|
+
session.subscribe(subscriber, error: &error)
|
300
|
+
guard error == nil else {
|
301
|
+
print(error!)
|
302
|
+
return
|
303
|
+
}
|
304
|
+
|
305
|
+
guard let subscriberView = subscriber.view else {
|
306
|
+
return
|
307
|
+
}
|
308
|
+
|
309
|
+
subscriberView.frame = UIScreen.main.bounds
|
310
|
+
remoteView.addSubview(subscriberView)
|
311
|
+
}
|
312
|
+
|
313
|
+
func session(_ session: OTSession, streamDestroyed stream: OTStream) {
|
314
|
+
print("A stream was destroyed in the session.\(session.sessionId)")
|
315
|
+
// var error = OTError()
|
316
|
+
// let progressPointer = AutoreleasingUnsafeMutablePointer<OTError?>.init(&error)
|
317
|
+
// if(session.sessionId == self.session?.sessionId){
|
318
|
+
// self.session?.disconnect(nil)
|
319
|
+
// self.dismiss(animated: true, completion: nil)
|
320
|
+
// }
|
321
|
+
if let subStream = subscriber?.stream, subStream.streamId == stream.streamId,!isProvider {
|
322
|
+
// cleanupSubscriber()
|
323
|
+
let userInfo = ["userInfo": ["isProvider": isProvider]]
|
324
|
+
NotificationCenter.default.post(name: NSNotification.Name(NotificationNames.videoEnded),object: nil,userInfo: userInfo)
|
325
|
+
self.session?.disconnect(nil)
|
326
|
+
self.dismiss(animated: true, completion: nil)
|
327
|
+
}
|
328
|
+
|
329
|
+
}
|
330
|
+
|
331
|
+
//Publisher methods
|
332
|
+
func publisher(_ publisher: OTPublisherKit, didFailWithError error: OTError) {
|
333
|
+
print("The publisher failed: \(error)")
|
334
|
+
}
|
335
|
+
|
336
|
+
func publisher(_ publisher: OTPublisher, didChangeCameraPosition position: AVCaptureDevice.Position) {
|
337
|
+
if position == .front {
|
338
|
+
// front camera
|
339
|
+
} else {
|
340
|
+
// back camera
|
341
|
+
}
|
342
|
+
}
|
343
|
+
|
344
|
+
//Subscriber methods
|
345
|
+
public func subscriberDidConnect(toStream subscriber: OTSubscriberKit) {
|
346
|
+
print("The subscriber did connect to the stream.")
|
347
|
+
}
|
348
|
+
|
349
|
+
public func subscriber(_ subscriber: OTSubscriberKit, didFailWithError error: OTError) {
|
350
|
+
print("The subscriber failed to connect to the stream.")
|
351
|
+
}
|
352
|
+
|
353
|
+
func subscriberVideoDisabled(_ subscriber: OTSubscriberKit, reason: OTSubscriberVideoEventReason) {
|
354
|
+
// Display the video disabled indicator
|
355
|
+
}
|
356
|
+
|
357
|
+
func subscriberVideoEnabled(_ subscriber: OTSubscriberKit, reason: OTSubscriberVideoEventReason) {
|
358
|
+
// Remove the video disabled indicator
|
359
|
+
}
|
360
|
+
|
361
|
+
@IBAction func endCallAction(_ sender: Any) {
|
362
|
+
//var error: OTError?
|
363
|
+
let userInfo = ["userInfo": ["isProvider": isProvider]]
|
364
|
+
NotificationCenter.default.post(name: NSNotification.Name(NotificationNames.videoEnded),object: nil,userInfo: userInfo)
|
365
|
+
cleanupSubscriber()
|
366
|
+
cleanupPublisher()
|
367
|
+
self.session?.disconnect(nil)
|
368
|
+
self.stopTimer()
|
369
|
+
// self.dismiss(animated: true, completion: nil)
|
370
|
+
}
|
371
|
+
fileprivate func cleanupSubscriber() {
|
372
|
+
subscriber?.view?.removeFromSuperview()
|
373
|
+
subscriber = nil
|
374
|
+
}
|
375
|
+
|
376
|
+
fileprivate func cleanupPublisher() {
|
377
|
+
publisher?.view?.removeFromSuperview()
|
378
|
+
publisher = nil
|
379
|
+
}
|
380
|
+
}
|
381
|
+
|
382
|
+
extension String {
|
383
|
+
func toJSON() -> Any? {
|
384
|
+
guard let data = self.data(using: .utf8, allowLossyConversion: false) else { return nil }
|
385
|
+
return try? JSONSerialization.jsonObject(with: data, options: .mutableContainers)
|
386
|
+
}
|
387
|
+
}
|
@@ -0,0 +1,10 @@
|
|
1
|
+
#import <UIKit/UIKit.h>
|
2
|
+
|
3
|
+
//! Project version number for Plugin.
|
4
|
+
FOUNDATION_EXPORT double PluginVersionNumber;
|
5
|
+
|
6
|
+
//! Project version string for Plugin.
|
7
|
+
FOUNDATION_EXPORT const unsigned char PluginVersionString[];
|
8
|
+
|
9
|
+
// In this header, you should import all the public headers of your framework using statements like #import <Plugin/PublicHeader.h>
|
10
|
+
|
@@ -0,0 +1,9 @@
|
|
1
|
+
#import <Foundation/Foundation.h>
|
2
|
+
#import <Capacitor/Capacitor.h>
|
3
|
+
|
4
|
+
// Define the plugin using the CAP_PLUGIN Macro, and
|
5
|
+
// each method the plugin supports using the CAP_PLUGIN_METHOD macro.
|
6
|
+
CAP_PLUGIN(vonagePlugin, "vonage",
|
7
|
+
CAP_PLUGIN_METHOD(echo, CAPPluginReturnPromise);
|
8
|
+
CAP_PLUGIN_METHOD(openVideoCallWindow, CAPPluginReturnPromise);
|
9
|
+
)
|
@@ -0,0 +1,80 @@
|
|
1
|
+
import Foundation
|
2
|
+
import Capacitor
|
3
|
+
|
4
|
+
/**
|
5
|
+
* Please read the Capacitor iOS Plugin Development Guide
|
6
|
+
* here: https://capacitorjs.com/docs/plugins/ios
|
7
|
+
*/
|
8
|
+
@objc(vonagePlugin)
|
9
|
+
public class vonagePlugin: CAPPlugin {
|
10
|
+
@objc func openVideoCallWindow(_ call: CAPPluginCall) {
|
11
|
+
|
12
|
+
let sessionId = call.getString("sessionId") ?? ""
|
13
|
+
let apiKey = call.getString("apiKey") ?? ""
|
14
|
+
let token = call.getString("token") ?? ""
|
15
|
+
|
16
|
+
let publisherName = call.getString("publisherName") ?? ""
|
17
|
+
let subscriberName = call.getString("subscriberName") ?? ""
|
18
|
+
let isProvider = call.getBool("isProvider") ?? false
|
19
|
+
|
20
|
+
DispatchQueue.main.async {
|
21
|
+
let vc = VideoChatViewController()
|
22
|
+
vc.kApiKey = apiKey
|
23
|
+
vc.kToken = token
|
24
|
+
vc.kSessionId = sessionId
|
25
|
+
vc.publisherName = publisherName
|
26
|
+
vc.subscriberName = subscriberName
|
27
|
+
vc.isProvider = isProvider
|
28
|
+
// vc.videoCallParam = value
|
29
|
+
vc.modalPresentationStyle = .fullScreen
|
30
|
+
self.bridge?.viewController?.present(vc, animated: true, completion: nil)
|
31
|
+
}
|
32
|
+
NotificationCenter.default.addObserver(self,selector:#selector(videoEnded(_:)),name: NSNotification.Name (NotificationNames.videoEnded),object: nil)
|
33
|
+
NotificationCenter.default.addObserver(self,selector:#selector(videoStarted(_:)),name: NSNotification.Name (NotificationNames.videoStarted),object: nil)
|
34
|
+
// if let visibleViewCtrl = UIApplication.topViewController() {
|
35
|
+
// // do whatever you want with your `visibleViewCtrl`
|
36
|
+
// print(visibleViewCtrl)
|
37
|
+
// DispatchQueue.main.async(execute: {
|
38
|
+
// let vc = VideoChatViewController()
|
39
|
+
// vc.kApiKey = apiKey
|
40
|
+
// vc.kToken = token
|
41
|
+
// vc.kSessionId = sessionId
|
42
|
+
// // vc.videoCallParam = value
|
43
|
+
// vc.modalPresentationStyle = .fullScreen
|
44
|
+
// visibleViewCtrl.present(vc, animated: true, completion: nil)})
|
45
|
+
// }
|
46
|
+
|
47
|
+
call.resolve(["value": "Video call initiated"])
|
48
|
+
}
|
49
|
+
@objc func videoEnded(_ notification: Notification){
|
50
|
+
self.notifyListeners(NotificationNames.videoEnded, data: notification.userInfo?["userInfo"] as? [String: Any] ?? [:])
|
51
|
+
NotificationCenter.default.removeObserver(self, name: NSNotification.Name(NotificationNames.videoEnded), object: nil)
|
52
|
+
}
|
53
|
+
@objc func videoStarted(_ notification: Notification){
|
54
|
+
self.notifyListeners(NotificationNames.videoStarted, data: notification.userInfo?["userInfo"] as? [String: Any] ?? [:])
|
55
|
+
NotificationCenter.default.removeObserver(self, name: NSNotification.Name(NotificationNames.videoStarted), object: nil)
|
56
|
+
}
|
57
|
+
}
|
58
|
+
extension UIApplication {
|
59
|
+
class func topViewController(base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
|
60
|
+
if let nav = base as? UINavigationController {
|
61
|
+
return topViewController(base: nav.visibleViewController)
|
62
|
+
}
|
63
|
+
|
64
|
+
if let tab = base as? UITabBarController {
|
65
|
+
if let selected = tab.selectedViewController {
|
66
|
+
return topViewController(base: selected)
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
if let presented = base?.presentedViewController {
|
71
|
+
return topViewController(base: presented)
|
72
|
+
}
|
73
|
+
|
74
|
+
return base
|
75
|
+
}
|
76
|
+
}
|
77
|
+
struct NotificationNames {
|
78
|
+
static let videoStarted = "VideoCallStarted"
|
79
|
+
static let videoEnded = "VideoCallEnded"
|
80
|
+
}
|
package/package.json
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
{
|
2
|
+
"name": "capacitor-plugin-vonage",
|
3
|
+
"version": "0.0.1",
|
4
|
+
"description": "opentok sdk capacitor plugin",
|
5
|
+
"main": "dist/plugin.cjs.js",
|
6
|
+
"module": "dist/esm/index.js",
|
7
|
+
"types": "dist/esm/index.d.ts",
|
8
|
+
"unpkg": "dist/plugin.js",
|
9
|
+
"files": [
|
10
|
+
"android/src/main/",
|
11
|
+
"android/build.gradle",
|
12
|
+
"dist/",
|
13
|
+
"ios/Plugin/",
|
14
|
+
"CapacitorPluginVonage.podspec"
|
15
|
+
],
|
16
|
+
"author": "",
|
17
|
+
"license": "MIT",
|
18
|
+
"repository": {
|
19
|
+
"type": "git",
|
20
|
+
"url": "git+https://github.com/vamsi3293/capacitor-plugin-vonage.git.git"
|
21
|
+
},
|
22
|
+
"bugs": {
|
23
|
+
"url": "https://github.com/vamsi3293/capacitor-plugin-vonage.git/issues"
|
24
|
+
},
|
25
|
+
"keywords": [
|
26
|
+
"capacitor",
|
27
|
+
"plugin",
|
28
|
+
"native"
|
29
|
+
],
|
30
|
+
"scripts": {
|
31
|
+
"verify": "npm run verify:ios && npm run verify:android && npm run verify:web",
|
32
|
+
"verify:ios": "cd ios && pod install && xcodebuild -workspace Plugin.xcworkspace -scheme Plugin -destination generic/platform=iOS && cd ..",
|
33
|
+
"verify:android": "cd android && ./gradlew clean build test && cd ..",
|
34
|
+
"verify:web": "npm run build",
|
35
|
+
"lint": "npm run eslint && npm run prettier -- --check && npm run swiftlint -- lint",
|
36
|
+
"fmt": "npm run eslint -- --fix && npm run prettier -- --write && npm run swiftlint -- --fix --format",
|
37
|
+
"eslint": "eslint . --ext ts",
|
38
|
+
"prettier": "prettier \"**/*.{css,html,ts,js,java}\"",
|
39
|
+
"swiftlint": "node-swiftlint",
|
40
|
+
"docgen": "docgen --api vonagePlugin --output-readme README.md --output-json dist/docs.json",
|
41
|
+
"build": "npm run clean && npm run docgen && tsc && rollup -c rollup.config.js",
|
42
|
+
"clean": "rimraf ./dist",
|
43
|
+
"watch": "tsc --watch",
|
44
|
+
"prepublishOnly": "npm run build"
|
45
|
+
},
|
46
|
+
"devDependencies": {
|
47
|
+
"@capacitor/android": "^5.0.0",
|
48
|
+
"@capacitor/core": "^5.0.0",
|
49
|
+
"@capacitor/docgen": "^0.0.18",
|
50
|
+
"@capacitor/ios": "^5.0.0",
|
51
|
+
"@ionic/eslint-config": "^0.3.0",
|
52
|
+
"@ionic/prettier-config": "^1.0.1",
|
53
|
+
"@ionic/swiftlint-config": "^1.1.2",
|
54
|
+
"eslint": "^7.11.0",
|
55
|
+
"prettier": "~2.3.0",
|
56
|
+
"prettier-plugin-java": "~1.0.2",
|
57
|
+
"rimraf": "^3.0.2",
|
58
|
+
"rollup": "^2.32.0",
|
59
|
+
"swiftlint": "^1.0.1",
|
60
|
+
"typescript": "~4.1.5"
|
61
|
+
},
|
62
|
+
"peerDependencies": {
|
63
|
+
"@capacitor/core": "^5.0.0"
|
64
|
+
},
|
65
|
+
"prettier": "@ionic/prettier-config",
|
66
|
+
"swiftlint": "@ionic/swiftlint-config",
|
67
|
+
"eslintConfig": {
|
68
|
+
"extends": "@ionic/eslint-config/recommended"
|
69
|
+
},
|
70
|
+
"capacitor": {
|
71
|
+
"ios": {
|
72
|
+
"src": "ios"
|
73
|
+
},
|
74
|
+
"android": {
|
75
|
+
"src": "android"
|
76
|
+
}
|
77
|
+
}
|
78
|
+
}
|