fix(ios, pip): update view hierarchy to present the rn view with view controller
This commit is contained in:
parent
6df2e4009c
commit
ddab27e292
|
@ -24,8 +24,14 @@
|
||||||
0BD906EA1EC0C00300C8C18E /* JitsiMeet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BD906E81EC0C00300C8C18E /* JitsiMeet.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
0BD906EA1EC0C00300C8C18E /* JitsiMeet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BD906E81EC0C00300C8C18E /* JitsiMeet.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
4E51B76425E5345E0038575A /* ScheenshareEventEmiter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E51B76225E5345E0038575A /* ScheenshareEventEmiter.h */; };
|
4E51B76425E5345E0038575A /* ScheenshareEventEmiter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E51B76225E5345E0038575A /* ScheenshareEventEmiter.h */; };
|
||||||
4E51B76525E5345E0038575A /* ScheenshareEventEmiter.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E51B76325E5345E0038575A /* ScheenshareEventEmiter.m */; };
|
4E51B76525E5345E0038575A /* ScheenshareEventEmiter.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E51B76325E5345E0038575A /* ScheenshareEventEmiter.m */; };
|
||||||
|
4EBA6E61286072E300B31882 /* JitsiMeetViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 4EBA6E5F286072E300B31882 /* JitsiMeetViewController.h */; };
|
||||||
|
4EBA6E62286072E300B31882 /* JitsiMeetViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EBA6E60286072E300B31882 /* JitsiMeetViewController.m */; };
|
||||||
|
4EBA6E652860B1E800B31882 /* JitsiMeetRenderingView.h in Headers */ = {isa = PBXBuildFile; fileRef = 4EBA6E632860B1E800B31882 /* JitsiMeetRenderingView.h */; };
|
||||||
|
4EBA6E662860B1E800B31882 /* JitsiMeetRenderingView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EBA6E642860B1E800B31882 /* JitsiMeetRenderingView.m */; };
|
||||||
4ED4FFF32721B9B90074E620 /* JitsiAudioSession.h in Headers */ = {isa = PBXBuildFile; fileRef = 4ED4FFF12721B9B90074E620 /* JitsiAudioSession.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
4ED4FFF32721B9B90074E620 /* JitsiAudioSession.h in Headers */ = {isa = PBXBuildFile; fileRef = 4ED4FFF12721B9B90074E620 /* JitsiAudioSession.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
4ED4FFF42721B9B90074E620 /* JitsiAudioSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ED4FFF22721B9B90074E620 /* JitsiAudioSession.m */; };
|
4ED4FFF42721B9B90074E620 /* JitsiAudioSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ED4FFF22721B9B90074E620 /* JitsiAudioSession.m */; };
|
||||||
|
4EEC9630286C73A2008705FA /* JitsiMeetView+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 4EEC962E286C73A2008705FA /* JitsiMeetView+Private.h */; };
|
||||||
|
4EEC9631286C73A2008705FA /* JitsiMeetView+Private.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EEC962F286C73A2008705FA /* JitsiMeetView+Private.m */; };
|
||||||
6F08DF7D4458EE3CF3F36F6D /* libPods-JitsiMeetSDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E4376CA6886DE68FD7A4294B /* libPods-JitsiMeetSDK.a */; };
|
6F08DF7D4458EE3CF3F36F6D /* libPods-JitsiMeetSDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E4376CA6886DE68FD7A4294B /* libPods-JitsiMeetSDK.a */; };
|
||||||
A4A934E9212F3ADB001E9388 /* Dropbox.m in Sources */ = {isa = PBXBuildFile; fileRef = A4A934E8212F3ADB001E9388 /* Dropbox.m */; };
|
A4A934E9212F3ADB001E9388 /* Dropbox.m in Sources */ = {isa = PBXBuildFile; fileRef = A4A934E8212F3ADB001E9388 /* Dropbox.m */; };
|
||||||
C6245F5D2053091D0040BE68 /* image-resize@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = C6245F5B2053091D0040BE68 /* image-resize@2x.png */; };
|
C6245F5D2053091D0040BE68 /* image-resize@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = C6245F5B2053091D0040BE68 /* image-resize@2x.png */; };
|
||||||
|
@ -79,9 +85,15 @@
|
||||||
0BD906E91EC0C00300C8C18E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
0BD906E91EC0C00300C8C18E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
4E51B76225E5345E0038575A /* ScheenshareEventEmiter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ScheenshareEventEmiter.h; sourceTree = "<group>"; };
|
4E51B76225E5345E0038575A /* ScheenshareEventEmiter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ScheenshareEventEmiter.h; sourceTree = "<group>"; };
|
||||||
4E51B76325E5345E0038575A /* ScheenshareEventEmiter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ScheenshareEventEmiter.m; sourceTree = "<group>"; };
|
4E51B76325E5345E0038575A /* ScheenshareEventEmiter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ScheenshareEventEmiter.m; sourceTree = "<group>"; };
|
||||||
|
4EBA6E5F286072E300B31882 /* JitsiMeetViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JitsiMeetViewController.h; sourceTree = "<group>"; };
|
||||||
|
4EBA6E60286072E300B31882 /* JitsiMeetViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JitsiMeetViewController.m; sourceTree = "<group>"; };
|
||||||
|
4EBA6E632860B1E800B31882 /* JitsiMeetRenderingView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JitsiMeetRenderingView.h; sourceTree = "<group>"; };
|
||||||
|
4EBA6E642860B1E800B31882 /* JitsiMeetRenderingView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JitsiMeetRenderingView.m; sourceTree = "<group>"; };
|
||||||
4ED4FFF12721B9B90074E620 /* JitsiAudioSession.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JitsiAudioSession.h; sourceTree = "<group>"; };
|
4ED4FFF12721B9B90074E620 /* JitsiAudioSession.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JitsiAudioSession.h; sourceTree = "<group>"; };
|
||||||
4ED4FFF22721B9B90074E620 /* JitsiAudioSession.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JitsiAudioSession.m; sourceTree = "<group>"; };
|
4ED4FFF22721B9B90074E620 /* JitsiAudioSession.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JitsiAudioSession.m; sourceTree = "<group>"; };
|
||||||
4ED4FFF52721BAE10074E620 /* JitsiAudioSession+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "JitsiAudioSession+Private.h"; sourceTree = "<group>"; };
|
4ED4FFF52721BAE10074E620 /* JitsiAudioSession+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "JitsiAudioSession+Private.h"; sourceTree = "<group>"; };
|
||||||
|
4EEC962E286C73A2008705FA /* JitsiMeetView+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "JitsiMeetView+Private.h"; sourceTree = "<group>"; };
|
||||||
|
4EEC962F286C73A2008705FA /* JitsiMeetView+Private.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "JitsiMeetView+Private.m"; sourceTree = "<group>"; };
|
||||||
891FE43DAD30BC8976683100 /* Pods-JitsiMeetSDK.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JitsiMeetSDK.release.xcconfig"; path = "../Pods/Target Support Files/Pods-JitsiMeetSDK/Pods-JitsiMeetSDK.release.xcconfig"; sourceTree = "<group>"; };
|
891FE43DAD30BC8976683100 /* Pods-JitsiMeetSDK.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JitsiMeetSDK.release.xcconfig"; path = "../Pods/Target Support Files/Pods-JitsiMeetSDK/Pods-JitsiMeetSDK.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
98E09B5C73D9036B4ED252FC /* Pods-JitsiMeet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JitsiMeet.debug.xcconfig"; path = "../Pods/Target Support Files/Pods-JitsiMeet/Pods-JitsiMeet.debug.xcconfig"; sourceTree = "<group>"; };
|
98E09B5C73D9036B4ED252FC /* Pods-JitsiMeet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JitsiMeet.debug.xcconfig"; path = "../Pods/Target Support Files/Pods-JitsiMeet/Pods-JitsiMeet.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
9C77CA3CC919B081F1A52982 /* Pods-JitsiMeet.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JitsiMeet.release.xcconfig"; path = "../Pods/Target Support Files/Pods-JitsiMeet/Pods-JitsiMeet.release.xcconfig"; sourceTree = "<group>"; };
|
9C77CA3CC919B081F1A52982 /* Pods-JitsiMeet.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JitsiMeet.release.xcconfig"; path = "../Pods/Target Support Files/Pods-JitsiMeet/Pods-JitsiMeet.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
@ -94,7 +106,6 @@
|
||||||
C69EFA0B209A0F660027712B /* JMCallKitListener.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JMCallKitListener.swift; sourceTree = "<group>"; };
|
C69EFA0B209A0F660027712B /* JMCallKitListener.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JMCallKitListener.swift; sourceTree = "<group>"; };
|
||||||
C6A3425E204EF76800E062DD /* DragGestureController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DragGestureController.swift; sourceTree = "<group>"; };
|
C6A3425E204EF76800E062DD /* DragGestureController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DragGestureController.swift; sourceTree = "<group>"; };
|
||||||
C6CC49AE207412CF000DFA42 /* PiPViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PiPViewCoordinator.swift; sourceTree = "<group>"; };
|
C6CC49AE207412CF000DFA42 /* PiPViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PiPViewCoordinator.swift; sourceTree = "<group>"; };
|
||||||
C6F99C13204DB63D0001F710 /* JitsiMeetView+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "JitsiMeetView+Private.h"; sourceTree = "<group>"; };
|
|
||||||
C81E9AB825AC5AD800B134D9 /* ExternalAPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ExternalAPI.h; sourceTree = "<group>"; };
|
C81E9AB825AC5AD800B134D9 /* ExternalAPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ExternalAPI.h; sourceTree = "<group>"; };
|
||||||
C8AFD27D2462C613000293D2 /* InfoPlistUtil.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InfoPlistUtil.h; sourceTree = "<group>"; };
|
C8AFD27D2462C613000293D2 /* InfoPlistUtil.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InfoPlistUtil.h; sourceTree = "<group>"; };
|
||||||
C8AFD27E2462C613000293D2 /* InfoPlistUtil.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InfoPlistUtil.m; sourceTree = "<group>"; };
|
C8AFD27E2462C613000293D2 /* InfoPlistUtil.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InfoPlistUtil.m; sourceTree = "<group>"; };
|
||||||
|
@ -194,12 +205,17 @@
|
||||||
DE65AACB2318028300290BEC /* JitsiMeetBaseLogHandler+Private.h */,
|
DE65AACB2318028300290BEC /* JitsiMeetBaseLogHandler+Private.h */,
|
||||||
DE81A2DD2317ED5400AE1940 /* JitsiMeetBaseLogHandler.m */,
|
DE81A2DD2317ED5400AE1940 /* JitsiMeetBaseLogHandler.m */,
|
||||||
0B412F161EDEC65D00B1A0A6 /* JitsiMeetView.h */,
|
0B412F161EDEC65D00B1A0A6 /* JitsiMeetView.h */,
|
||||||
|
4EEC962E286C73A2008705FA /* JitsiMeetView+Private.h */,
|
||||||
|
4EEC962F286C73A2008705FA /* JitsiMeetView+Private.m */,
|
||||||
0B412F171EDEC65D00B1A0A6 /* JitsiMeetView.m */,
|
0B412F171EDEC65D00B1A0A6 /* JitsiMeetView.m */,
|
||||||
|
4EBA6E632860B1E800B31882 /* JitsiMeetRenderingView.h */,
|
||||||
|
4EBA6E642860B1E800B31882 /* JitsiMeetRenderingView.m */,
|
||||||
|
4EBA6E5F286072E300B31882 /* JitsiMeetViewController.h */,
|
||||||
|
4EBA6E60286072E300B31882 /* JitsiMeetViewController.m */,
|
||||||
DE81A2D72316AC7600AE1940 /* LogBridge.m */,
|
DE81A2D72316AC7600AE1940 /* LogBridge.m */,
|
||||||
DE65AAC92317FFCD00290BEC /* LogUtils.h */,
|
DE65AAC92317FFCD00290BEC /* LogUtils.h */,
|
||||||
DEAFA777229EAD3B0033A7FA /* RNRootView.h */,
|
DEAFA777229EAD3B0033A7FA /* RNRootView.h */,
|
||||||
DEAFA778229EAD520033A7FA /* RNRootView.m */,
|
DEAFA778229EAD520033A7FA /* RNRootView.m */,
|
||||||
C6F99C13204DB63D0001F710 /* JitsiMeetView+Private.h */,
|
|
||||||
0B412F1B1EDEC80100B1A0A6 /* JitsiMeetViewDelegate.h */,
|
0B412F1B1EDEC80100B1A0A6 /* JitsiMeetViewDelegate.h */,
|
||||||
DEFC743D21B178FA00E4DD96 /* LocaleDetector.m */,
|
DEFC743D21B178FA00E4DD96 /* LocaleDetector.m */,
|
||||||
C6A3426B204F127900E062DD /* picture-in-picture */,
|
C6A3426B204F127900E062DD /* picture-in-picture */,
|
||||||
|
@ -284,11 +300,14 @@
|
||||||
DEA9F284258A5D9900D4CD74 /* JitsiMeetSDK.h in Headers */,
|
DEA9F284258A5D9900D4CD74 /* JitsiMeetSDK.h in Headers */,
|
||||||
4E51B76425E5345E0038575A /* ScheenshareEventEmiter.h in Headers */,
|
4E51B76425E5345E0038575A /* ScheenshareEventEmiter.h in Headers */,
|
||||||
DE65AACC2318028300290BEC /* JitsiMeetBaseLogHandler+Private.h in Headers */,
|
DE65AACC2318028300290BEC /* JitsiMeetBaseLogHandler+Private.h in Headers */,
|
||||||
|
4EBA6E652860B1E800B31882 /* JitsiMeetRenderingView.h in Headers */,
|
||||||
0B412F221EDEF6EA00B1A0A6 /* JitsiMeetViewDelegate.h in Headers */,
|
0B412F221EDEF6EA00B1A0A6 /* JitsiMeetViewDelegate.h in Headers */,
|
||||||
4ED4FFF32721B9B90074E620 /* JitsiAudioSession.h in Headers */,
|
4ED4FFF32721B9B90074E620 /* JitsiAudioSession.h in Headers */,
|
||||||
|
4EEC9630286C73A2008705FA /* JitsiMeetView+Private.h in Headers */,
|
||||||
0BD906EA1EC0C00300C8C18E /* JitsiMeet.h in Headers */,
|
0BD906EA1EC0C00300C8C18E /* JitsiMeet.h in Headers */,
|
||||||
DE81A2D42316AC4D00AE1940 /* JitsiMeetLogger.h in Headers */,
|
DE81A2D42316AC4D00AE1940 /* JitsiMeetLogger.h in Headers */,
|
||||||
DE65AACA2317FFCD00290BEC /* LogUtils.h in Headers */,
|
DE65AACA2317FFCD00290BEC /* LogUtils.h in Headers */,
|
||||||
|
4EBA6E61286072E300B31882 /* JitsiMeetViewController.h in Headers */,
|
||||||
DEAD3226220C497000E93636 /* JitsiMeetConferenceOptions.h in Headers */,
|
DEAD3226220C497000E93636 /* JitsiMeetConferenceOptions.h in Headers */,
|
||||||
C81E9AB925AC5AD800B134D9 /* ExternalAPI.h in Headers */,
|
C81E9AB925AC5AD800B134D9 /* ExternalAPI.h in Headers */,
|
||||||
C8AFD27F2462C613000293D2 /* InfoPlistUtil.h in Headers */,
|
C8AFD27F2462C613000293D2 /* InfoPlistUtil.h in Headers */,
|
||||||
|
@ -449,6 +468,7 @@
|
||||||
files = (
|
files = (
|
||||||
0BB9AD7B1F5EC8F4001C08DB /* CallKit.m in Sources */,
|
0BB9AD7B1F5EC8F4001C08DB /* CallKit.m in Sources */,
|
||||||
DE81A2DF2317ED5400AE1940 /* JitsiMeetBaseLogHandler.m in Sources */,
|
DE81A2DF2317ED5400AE1940 /* JitsiMeetBaseLogHandler.m in Sources */,
|
||||||
|
4EBA6E662860B1E800B31882 /* JitsiMeetRenderingView.m in Sources */,
|
||||||
4ED4FFF42721B9B90074E620 /* JitsiAudioSession.m in Sources */,
|
4ED4FFF42721B9B90074E620 /* JitsiAudioSession.m in Sources */,
|
||||||
0BB9AD7D1F60356D001C08DB /* AppInfo.m in Sources */,
|
0BB9AD7D1F60356D001C08DB /* AppInfo.m in Sources */,
|
||||||
DE81A2D92316AC7600AE1940 /* LogBridge.m in Sources */,
|
DE81A2D92316AC7600AE1940 /* LogBridge.m in Sources */,
|
||||||
|
@ -465,9 +485,11 @@
|
||||||
0BCA49611EC4B6C600B793EE /* Proximity.m in Sources */,
|
0BCA49611EC4B6C600B793EE /* Proximity.m in Sources */,
|
||||||
C69EFA0C209A0F660027712B /* JMCallKitEmitter.swift in Sources */,
|
C69EFA0C209A0F660027712B /* JMCallKitEmitter.swift in Sources */,
|
||||||
DEFE535621FB2E8300011A3A /* ReactUtils.m in Sources */,
|
DEFE535621FB2E8300011A3A /* ReactUtils.m in Sources */,
|
||||||
|
4EEC9631286C73A2008705FA /* JitsiMeetView+Private.m in Sources */,
|
||||||
C6A34261204EF76800E062DD /* DragGestureController.swift in Sources */,
|
C6A34261204EF76800E062DD /* DragGestureController.swift in Sources */,
|
||||||
4E51B76525E5345E0038575A /* ScheenshareEventEmiter.m in Sources */,
|
4E51B76525E5345E0038575A /* ScheenshareEventEmiter.m in Sources */,
|
||||||
A4A934E9212F3ADB001E9388 /* Dropbox.m in Sources */,
|
A4A934E9212F3ADB001E9388 /* Dropbox.m in Sources */,
|
||||||
|
4EBA6E62286072E300B31882 /* JitsiMeetViewController.m in Sources */,
|
||||||
C69EFA0D209A0F660027712B /* JMCallKitProxy.swift in Sources */,
|
C69EFA0D209A0F660027712B /* JMCallKitProxy.swift in Sources */,
|
||||||
DE81A2D52316AC4D00AE1940 /* JitsiMeetLogger.m in Sources */,
|
DE81A2D52316AC4D00AE1940 /* JitsiMeetLogger.m in Sources */,
|
||||||
C69EFA0E209A0F660027712B /* JMCallKitListener.swift in Sources */,
|
C69EFA0E209A0F660027712B /* JMCallKitListener.swift in Sources */,
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
#import <React/RCTBridgeModule.h>
|
#import <React/RCTBridgeModule.h>
|
||||||
#import <React/RCTEventEmitter.h>
|
#import <React/RCTEventEmitter.h>
|
||||||
|
|
||||||
|
static NSString * const sendEventNotificationName = @"org.jitsi.meet.SendEvent";
|
||||||
|
|
||||||
@interface ExternalAPI : RCTEventEmitter<RCTBridgeModule>
|
@interface ExternalAPI : RCTEventEmitter<RCTBridgeModule>
|
||||||
|
|
||||||
- (void)sendHangUp;
|
- (void)sendHangUp;
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "ExternalAPI.h"
|
#import "ExternalAPI.h"
|
||||||
#import "JitsiMeetView+Private.h"
|
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
static NSString * const hangUpAction = @"org.jitsi.meet.HANG_UP";
|
static NSString * const hangUpAction = @"org.jitsi.meet.HANG_UP";
|
||||||
|
@ -91,31 +90,14 @@ RCT_EXPORT_MODULE();
|
||||||
RCT_EXPORT_METHOD(sendEvent:(NSString *)name
|
RCT_EXPORT_METHOD(sendEvent:(NSString *)name
|
||||||
data:(NSDictionary *)data
|
data:(NSDictionary *)data
|
||||||
scope:(NSString *)scope) {
|
scope:(NSString *)scope) {
|
||||||
// The JavaScript App needs to provide uniquely identifying information to
|
|
||||||
// the native ExternalAPI module so that the latter may match the former
|
|
||||||
// to the native JitsiMeetView which hosts it.
|
|
||||||
JitsiMeetView *view = [JitsiMeetView viewForExternalAPIScope:scope];
|
|
||||||
|
|
||||||
if (!view) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
id delegate = view.delegate;
|
|
||||||
|
|
||||||
if (!delegate) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ([name isEqual: @"PARTICIPANTS_INFO_RETRIEVED"]) {
|
if ([name isEqual: @"PARTICIPANTS_INFO_RETRIEVED"]) {
|
||||||
[self onParticipantsInfoRetrieved: data];
|
[self onParticipantsInfoRetrieved: data];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SEL sel = NSSelectorFromString([self methodNameFromEventName:name]);
|
[[NSNotificationCenter defaultCenter] postNotificationName:sendEventNotificationName
|
||||||
|
object:nil
|
||||||
if (sel && [delegate respondsToSelector:sel]) {
|
userInfo:@{@"name": name, @"data": data}];
|
||||||
[delegate performSelector:sel withObject:data];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) onParticipantsInfoRetrieved:(NSDictionary *)data {
|
- (void) onParticipantsInfoRetrieved:(NSDictionary *)data {
|
||||||
|
@ -127,28 +109,6 @@ RCT_EXPORT_METHOD(sendEvent:(NSString *)name
|
||||||
[participantInfoCompletionHandlers removeObjectForKey:completionHandlerId];
|
[participantInfoCompletionHandlers removeObjectForKey:completionHandlerId];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts a specific event name i.e. redux action type description to a
|
|
||||||
* method name.
|
|
||||||
*
|
|
||||||
* @param eventName The event name to convert to a method name.
|
|
||||||
* @return A method name constructed from the specified `eventName`.
|
|
||||||
*/
|
|
||||||
- (NSString *)methodNameFromEventName:(NSString *)eventName {
|
|
||||||
NSMutableString *methodName
|
|
||||||
= [NSMutableString stringWithCapacity:eventName.length];
|
|
||||||
|
|
||||||
for (NSString *c in [eventName componentsSeparatedByString:@"_"]) {
|
|
||||||
if (c.length) {
|
|
||||||
[methodName appendString:
|
|
||||||
methodName.length ? c.capitalizedString : c.lowercaseString];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
[methodName appendString:@":"];
|
|
||||||
|
|
||||||
return methodName;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)sendHangUp {
|
- (void)sendHangUp {
|
||||||
[self sendEventWithName:hangUpAction body:nil];
|
[self sendEventWithName:hangUpAction body:nil];
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import <Intents/Intents.h>
|
#import <Intents/Intents.h>
|
||||||
|
#import <RNGoogleSignin/RNGoogleSignin.h>
|
||||||
|
#import <WebRTC/RTCLogging.h>
|
||||||
|
|
||||||
#import "Dropbox.h"
|
#import "Dropbox.h"
|
||||||
#import "JitsiMeet+Private.h"
|
#import "JitsiMeet+Private.h"
|
||||||
|
@ -25,9 +27,6 @@
|
||||||
#import "RNSplashScreen.h"
|
#import "RNSplashScreen.h"
|
||||||
#import "ScheenshareEventEmiter.h"
|
#import "ScheenshareEventEmiter.h"
|
||||||
|
|
||||||
#import <RNGoogleSignin/RNGoogleSignin.h>
|
|
||||||
#import <WebRTC/RTCLogging.h>
|
|
||||||
|
|
||||||
@implementation JitsiMeet {
|
@implementation JitsiMeet {
|
||||||
RCTBridgeWrapper *_bridgeWrapper;
|
RCTBridgeWrapper *_bridgeWrapper;
|
||||||
NSDictionary *_launchOptions;
|
NSDictionary *_launchOptions;
|
||||||
|
@ -87,8 +86,12 @@
|
||||||
restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> *))restorationHandler {
|
restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> *))restorationHandler {
|
||||||
|
|
||||||
JitsiMeetConferenceOptions *options = [self optionsFromUserActivity:userActivity];
|
JitsiMeetConferenceOptions *options = [self optionsFromUserActivity:userActivity];
|
||||||
|
if (options) {
|
||||||
|
[JitsiMeetView updateProps:[options asProps]];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return options && [JitsiMeetView setPropsInViews:[options asProps]];
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)application:(UIApplication *)app
|
- (BOOL)application:(UIApplication *)app
|
||||||
|
@ -112,8 +115,9 @@
|
||||||
JitsiMeetConferenceOptions *conferenceOptions = [JitsiMeetConferenceOptions fromBuilder:^(JitsiMeetConferenceOptionsBuilder *builder) {
|
JitsiMeetConferenceOptions *conferenceOptions = [JitsiMeetConferenceOptions fromBuilder:^(JitsiMeetConferenceOptionsBuilder *builder) {
|
||||||
builder.room = [url absoluteString];
|
builder.room = [url absoluteString];
|
||||||
}];
|
}];
|
||||||
|
[JitsiMeetView updateProps:[conferenceOptions asProps]];
|
||||||
|
|
||||||
return [JitsiMeetView setPropsInViews:[conferenceOptions asProps]];
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Utility methods
|
#pragma mark - Utility methods
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* Copyright @ 2022-present 8x8, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#import "JitsiMeetViewDelegate.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface JitsiMeetRenderingView : UIView
|
||||||
|
|
||||||
|
@property (nonatomic, assign) BOOL isPiPEnabled;
|
||||||
|
|
||||||
|
- (void)setProps:(NSDictionary *_Nonnull)newProps;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
|
@ -0,0 +1,103 @@
|
||||||
|
/*
|
||||||
|
* Copyright @ 2022-present 8x8, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
#include <mach/mach_time.h>
|
||||||
|
|
||||||
|
#import "JitsiMeetRenderingView.h"
|
||||||
|
#import "ReactUtils.h"
|
||||||
|
#import "RNRootView.h"
|
||||||
|
#import "JitsiMeet+Private.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Backwards compatibility: turn the boolean prop into a feature flag.
|
||||||
|
*/
|
||||||
|
static NSString *const PiPEnabledFeatureFlag = @"pip.enabled";
|
||||||
|
|
||||||
|
@interface JitsiMeetRenderingView ()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The unique identifier of this `JitsiMeetView` within the process for the
|
||||||
|
* purposes of `ExternalAPI`. The name scope was inspired by postis which we
|
||||||
|
* use on Web for the similar purposes of the iframe-based external API.
|
||||||
|
*/
|
||||||
|
@property (nonatomic, strong) NSString *externalAPIScope;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation JitsiMeetRenderingView {
|
||||||
|
/**
|
||||||
|
* React Native view where the entire content will be rendered.
|
||||||
|
*/
|
||||||
|
RNRootView *rootView;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)init {
|
||||||
|
self = [super init];
|
||||||
|
if (self) {
|
||||||
|
// Hook this JitsiMeetView into ExternalAPI.
|
||||||
|
self.externalAPIScope = [NSUUID UUID].UUIDString;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Passes the given props to the React Native application. The props which we pass
|
||||||
|
* are a combination of 3 different sources:
|
||||||
|
*
|
||||||
|
* - JitsiMeet.defaultConferenceOptions
|
||||||
|
* - This function's parameters
|
||||||
|
* - Some extras which are added by this function
|
||||||
|
*/
|
||||||
|
- (void)setProps:(NSDictionary *_Nonnull)newProps {
|
||||||
|
NSMutableDictionary *props = mergeProps([[JitsiMeet sharedInstance] getDefaultProps], newProps);
|
||||||
|
|
||||||
|
// Set the PiP flag if it wasn't manually set.
|
||||||
|
NSMutableDictionary *featureFlags = props[@"flags"];
|
||||||
|
// TODO: temporary implementation
|
||||||
|
if (featureFlags[PiPEnabledFeatureFlag] == nil) {
|
||||||
|
featureFlags[PiPEnabledFeatureFlag] = @(self.isPiPEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
props[@"externalAPIScope"] = self.externalAPIScope;
|
||||||
|
|
||||||
|
// This method is supposed to be imperative i.e. a second
|
||||||
|
// invocation with one and the same URL is expected to join the respective
|
||||||
|
// conference again if the first invocation was followed by leaving the
|
||||||
|
// conference. However, React and, respectively,
|
||||||
|
// appProperties/initialProperties are declarative expressions i.e. one and
|
||||||
|
// the same URL will not trigger an automatic re-render in the JavaScript
|
||||||
|
// source code. The workaround implemented below introduces imperativeness
|
||||||
|
// in React Component props by defining a unique value per invocation.
|
||||||
|
props[@"timestamp"] = @(mach_absolute_time());
|
||||||
|
|
||||||
|
if (rootView) {
|
||||||
|
// Update props with the new URL.
|
||||||
|
rootView.appProperties = props;
|
||||||
|
} else {
|
||||||
|
RCTBridge *bridge = [[JitsiMeet sharedInstance] getReactBridge];
|
||||||
|
rootView = [[RNRootView alloc] initWithBridge:bridge
|
||||||
|
moduleName:@"App"
|
||||||
|
initialProperties:props];
|
||||||
|
rootView.backgroundColor = self.backgroundColor;
|
||||||
|
|
||||||
|
// Add rootView as a subview which completely covers this one.
|
||||||
|
[rootView setFrame:[self bounds]];
|
||||||
|
rootView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||||
|
[self addSubview:rootView];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -1,6 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright @ 2018-present 8x8, Inc.
|
* Copyright @ 2022-present 8x8, Inc.
|
||||||
* Copyright @ 2017-2018 Atlassian Pty Ltd
|
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -15,11 +14,16 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import "JitsiMeetView.h"
|
#import <JitsiMeetSDK/JitsiMeetSDK.h>
|
||||||
|
|
||||||
@interface JitsiMeetView ()
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
+ (instancetype _Nullable)viewForExternalAPIScope:(NSString *_Nonnull)externalAPIScope;
|
static NSString * const updateViewPropsNotificationName = @"org.jitsi.meet.UpdateViewProps";
|
||||||
+ (BOOL)setPropsInViews:(NSDictionary *_Nonnull)newProps;
|
|
||||||
|
@interface JitsiMeetView (Private)
|
||||||
|
|
||||||
|
+ (void)updateProps:(NSDictionary *_Nonnull)newProps;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Copyright @ 2022-present 8x8, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import "JitsiMeetView+Private.h"
|
||||||
|
|
||||||
|
@implementation JitsiMeetView (Private)
|
||||||
|
|
||||||
|
+ (void)updateProps:(NSDictionary *_Nonnull)newProps {
|
||||||
|
[[NSNotificationCenter defaultCenter] postNotificationName:updateViewPropsNotificationName object:nil userInfo:@{@"props": newProps}];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -20,43 +20,22 @@
|
||||||
#import "ExternalAPI.h"
|
#import "ExternalAPI.h"
|
||||||
#import "JitsiMeet+Private.h"
|
#import "JitsiMeet+Private.h"
|
||||||
#import "JitsiMeetConferenceOptions+Private.h"
|
#import "JitsiMeetConferenceOptions+Private.h"
|
||||||
#import "JitsiMeetView+Private.h"
|
#import "JitsiMeetView.h"
|
||||||
|
#import "JitsiMeetViewController.h"
|
||||||
#import "ReactUtils.h"
|
#import "ReactUtils.h"
|
||||||
#import "RNRootView.h"
|
#import "RNRootView.h"
|
||||||
|
|
||||||
|
@interface JitsiMeetView ()
|
||||||
|
|
||||||
/**
|
@property (nonatomic, strong) JitsiMeetViewController *jitsiMeetViewController;
|
||||||
* Backwards compatibility: turn the boolean prop into a feature flag.
|
@property (nonatomic, strong) UINavigationController *navController;
|
||||||
*/
|
@property (nonatomic, readonly) BOOL isPiPEnabled;
|
||||||
static NSString *const PiPEnabledFeatureFlag = @"pip.enabled";
|
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
@implementation JitsiMeetView {
|
@implementation JitsiMeetView
|
||||||
/**
|
|
||||||
* The unique identifier of this `JitsiMeetView` within the process for the
|
|
||||||
* purposes of `ExternalAPI`. The name scope was inspired by postis which we
|
|
||||||
* use on Web for the similar purposes of the iframe-based external API.
|
|
||||||
*/
|
|
||||||
NSString *externalAPIScope;
|
|
||||||
|
|
||||||
/**
|
@dynamic isPiPEnabled;
|
||||||
* React Native view where the entire content will be rendered.
|
|
||||||
*/
|
|
||||||
RNRootView *rootView;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The `JitsiMeetView`s associated with their `ExternalAPI` scopes (i.e. unique
|
|
||||||
* identifiers within the process).
|
|
||||||
*/
|
|
||||||
static NSMapTable<NSString *, JitsiMeetView *> *views;
|
|
||||||
/**
|
|
||||||
* This gets called automagically when the program starts.
|
|
||||||
*/
|
|
||||||
__attribute__((constructor))
|
|
||||||
static void initializeViewsMap() {
|
|
||||||
views = [NSMapTable strongToWeakObjectsMapTable];
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark Initializers
|
#pragma mark Initializers
|
||||||
|
|
||||||
|
@ -87,6 +66,10 @@ static void initializeViewsMap() {
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)dealloc {
|
||||||
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal initialization:
|
* Internal initialization:
|
||||||
*
|
*
|
||||||
|
@ -94,70 +77,57 @@ static void initializeViewsMap() {
|
||||||
* - initializes the external API scope
|
* - initializes the external API scope
|
||||||
*/
|
*/
|
||||||
- (void)initWithXXX {
|
- (void)initWithXXX {
|
||||||
// Hook this JitsiMeetView into ExternalAPI.
|
self.jitsiMeetViewController = [[JitsiMeetViewController alloc] init];
|
||||||
externalAPIScope = [NSUUID UUID].UUIDString;
|
self.jitsiMeetViewController.view.frame = [self bounds];
|
||||||
[views setObject:self forKey:externalAPIScope];
|
[self addSubview:self.jitsiMeetViewController.view];
|
||||||
|
|
||||||
// Set a background color which is in accord with the JavaScript and Android
|
[self registerObservers];
|
||||||
// parts of the application and causes less perceived visual flicker than
|
|
||||||
// the default background color.
|
|
||||||
self.backgroundColor
|
|
||||||
= [UIColor colorWithRed:.07f green:.07f blue:.07f alpha:1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark API
|
#pragma mark API
|
||||||
|
|
||||||
- (void)join:(JitsiMeetConferenceOptions *)options {
|
- (void)join:(JitsiMeetConferenceOptions *)options {
|
||||||
[self setProps:options == nil ? @{} : [options asProps]];
|
[self.jitsiMeetViewController join:options withPiP:self.isPiPEnabled];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)leave {
|
- (void)leave {
|
||||||
[self setProps:@{}];
|
[self.jitsiMeetViewController leave];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)hangUp {
|
- (void)hangUp {
|
||||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
[self.jitsiMeetViewController hangUp];
|
||||||
[externalAPI sendHangUp];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setAudioMuted:(BOOL)muted {
|
- (void)setAudioMuted:(BOOL)muted {
|
||||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
[self.jitsiMeetViewController setAudioMuted:muted];
|
||||||
[externalAPI sendSetAudioMuted:muted];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)sendEndpointTextMessage:(NSString * _Nonnull)message :(NSString * _Nullable)to {
|
- (void)sendEndpointTextMessage:(NSString * _Nonnull)message :(NSString * _Nullable)to {
|
||||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
[self.jitsiMeetViewController sendEndpointTextMessage:message :to];
|
||||||
[externalAPI sendEndpointTextMessage:message :to];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)toggleScreenShare:(BOOL)enabled {
|
- (void)toggleScreenShare:(BOOL)enabled {
|
||||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
[self.jitsiMeetViewController toggleScreenShare:enabled];
|
||||||
[externalAPI toggleScreenShare:enabled];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)retrieveParticipantsInfo:(void (^ _Nonnull)(NSArray * _Nullable))completionHandler {
|
- (void)retrieveParticipantsInfo:(void (^ _Nonnull)(NSArray * _Nullable))completionHandler {
|
||||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
[self.jitsiMeetViewController retrieveParticipantsInfo:completionHandler];
|
||||||
[externalAPI retrieveParticipantsInfo:completionHandler];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)openChat:(NSString*)to {
|
- (void)openChat:(NSString*)to {
|
||||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
[self.jitsiMeetViewController openChat:to];
|
||||||
[externalAPI openChat:to];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)closeChat {
|
- (void)closeChat {
|
||||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
[self.jitsiMeetViewController closeChat];
|
||||||
[externalAPI closeChat];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)sendChatMessage:(NSString * _Nonnull)message :(NSString * _Nullable)to {
|
- (void)sendChatMessage:(NSString * _Nonnull)message :(NSString * _Nullable)to {
|
||||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
[self.jitsiMeetViewController sendChatMessage:message :to];
|
||||||
[externalAPI sendChatMessage:message :to];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setVideoMuted:(BOOL)muted {
|
- (void)setVideoMuted:(BOOL)muted {
|
||||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
[self.jitsiMeetViewController setVideoMuted:muted];
|
||||||
[externalAPI sendSetVideoMuted:muted];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setClosedCaptionsEnabled:(BOOL)enabled {
|
- (void)setClosedCaptionsEnabled:(BOOL)enabled {
|
||||||
|
@ -165,79 +135,47 @@ static void initializeViewsMap() {
|
||||||
[externalAPI sendSetClosedCaptionsEnabled:enabled];
|
[externalAPI sendSetClosedCaptionsEnabled:enabled];
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark Private methods
|
#pragma mark Private
|
||||||
|
|
||||||
|
- (BOOL)isPiPEnabled {
|
||||||
|
return self.delegate && [self.delegate respondsToSelector:@selector(enterPictureInPicture:)];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)registerObservers {
|
||||||
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleSendEventNotification:) name:sendEventNotificationName object:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)handleSendEventNotification:(NSNotification *)notification {
|
||||||
|
NSString *eventName = notification.userInfo[@"name"];
|
||||||
|
NSString *eventData = notification.userInfo[@"data"];
|
||||||
|
|
||||||
|
SEL sel = NSSelectorFromString([self methodNameFromEventName:eventName]);
|
||||||
|
|
||||||
|
if (sel && [self.delegate respondsToSelector:sel]) {
|
||||||
|
[self.delegate performSelector:sel withObject:eventData];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Passes the given props to the React Native application. The props which we pass
|
* Converts a specific event name i.e. redux action type description to a
|
||||||
* are a combination of 3 different sources:
|
* method name.
|
||||||
*
|
*
|
||||||
* - JitsiMeet.defaultConferenceOptions
|
* @param eventName The event name to convert to a method name.
|
||||||
* - This function's parameters
|
* @return A method name constructed from the specified `eventName`.
|
||||||
* - Some extras which are added by this function
|
|
||||||
*/
|
*/
|
||||||
- (void)setProps:(NSDictionary *_Nonnull)newProps {
|
- (NSString *)methodNameFromEventName:(NSString *)eventName {
|
||||||
NSMutableDictionary *props = mergeProps([[JitsiMeet sharedInstance] getDefaultProps], newProps);
|
NSMutableString *methodName
|
||||||
|
= [NSMutableString stringWithCapacity:eventName.length];
|
||||||
|
|
||||||
// Set the PiP flag if it wasn't manually set.
|
for (NSString *c in [eventName componentsSeparatedByString:@"_"]) {
|
||||||
NSMutableDictionary *featureFlags = props[@"flags"];
|
if (c.length) {
|
||||||
if (featureFlags[PiPEnabledFeatureFlag] == nil) {
|
[methodName appendString:
|
||||||
featureFlags[PiPEnabledFeatureFlag]
|
methodName.length ? c.capitalizedString : c.lowercaseString];
|
||||||
= [NSNumber numberWithBool:
|
}
|
||||||
self.delegate && [self.delegate respondsToSelector:@selector(enterPictureInPicture:)]];
|
}
|
||||||
}
|
[methodName appendString:@":"];
|
||||||
|
|
||||||
props[@"externalAPIScope"] = externalAPIScope;
|
return methodName;
|
||||||
|
|
||||||
// This method is supposed to be imperative i.e. a second
|
|
||||||
// invocation with one and the same URL is expected to join the respective
|
|
||||||
// conference again if the first invocation was followed by leaving the
|
|
||||||
// conference. However, React and, respectively,
|
|
||||||
// appProperties/initialProperties are declarative expressions i.e. one and
|
|
||||||
// the same URL will not trigger an automatic re-render in the JavaScript
|
|
||||||
// source code. The workaround implemented below introduces imperativeness
|
|
||||||
// in React Component props by defining a unique value per invocation.
|
|
||||||
props[@"timestamp"] = @(mach_absolute_time());
|
|
||||||
|
|
||||||
if (rootView) {
|
|
||||||
// Update props with the new URL.
|
|
||||||
rootView.appProperties = props;
|
|
||||||
} else {
|
|
||||||
RCTBridge *bridge = [[JitsiMeet sharedInstance] getReactBridge];
|
|
||||||
rootView
|
|
||||||
= [[RNRootView alloc] initWithBridge:bridge
|
|
||||||
moduleName:@"App"
|
|
||||||
initialProperties:props];
|
|
||||||
rootView.backgroundColor = self.backgroundColor;
|
|
||||||
|
|
||||||
// Add rootView as a subview which completely covers this one.
|
|
||||||
[rootView setFrame:[self bounds]];
|
|
||||||
rootView.autoresizingMask
|
|
||||||
= UIViewAutoresizingFlexibleWidth
|
|
||||||
| UIViewAutoresizingFlexibleHeight;
|
|
||||||
[self addSubview:rootView];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (BOOL)setPropsInViews:(NSDictionary *_Nonnull)newProps {
|
|
||||||
BOOL handled = NO;
|
|
||||||
|
|
||||||
if (views) {
|
|
||||||
for (NSString *externalAPIScope in views) {
|
|
||||||
JitsiMeetView *view
|
|
||||||
= [self viewForExternalAPIScope:externalAPIScope];
|
|
||||||
|
|
||||||
if (view) {
|
|
||||||
[view setProps:newProps];
|
|
||||||
handled = YES;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (instancetype)viewForExternalAPIScope:(NSString *)externalAPIScope {
|
|
||||||
return [views objectForKey:externalAPIScope];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* Copyright @ 2022-present 8x8, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#import "JitsiMeetConferenceOptions.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface JitsiMeetViewController : UIViewController
|
||||||
|
|
||||||
|
- (void)join:(JitsiMeetConferenceOptions *)options withPiP:(BOOL)enablePiP;
|
||||||
|
- (void)leave;
|
||||||
|
- (void)hangUp;
|
||||||
|
- (void)setAudioMuted:(BOOL)muted;
|
||||||
|
- (void)sendEndpointTextMessage:(NSString * _Nonnull)message :(NSString * _Nullable)to;
|
||||||
|
- (void)toggleScreenShare:(BOOL)enabled;
|
||||||
|
- (void)retrieveParticipantsInfo:(void (^ _Nonnull)(NSArray * _Nullable))completionHandler;
|
||||||
|
- (void)openChat:(NSString*)to;
|
||||||
|
- (void)closeChat;
|
||||||
|
- (void)sendChatMessage:(NSString * _Nonnull)message :(NSString * _Nullable)to;
|
||||||
|
- (void)setVideoMuted:(BOOL)muted;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
|
@ -0,0 +1,127 @@
|
||||||
|
/*
|
||||||
|
* Copyright @ 2022-present 8x8, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import "JitsiMeetViewController.h"
|
||||||
|
#import "JitsiMeet+Private.h"
|
||||||
|
#import "JitsiMeetConferenceOptions+Private.h"
|
||||||
|
#import "JitsiMeetRenderingView.h"
|
||||||
|
#import "JitsiMeetView+Private.h"
|
||||||
|
|
||||||
|
@interface JitsiMeetViewController ()
|
||||||
|
|
||||||
|
@property (strong, nonatomic) JitsiMeetRenderingView *view;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation JitsiMeetViewController
|
||||||
|
|
||||||
|
@dynamic view;
|
||||||
|
|
||||||
|
- (instancetype)init {
|
||||||
|
self = [super init];
|
||||||
|
if (self) {
|
||||||
|
[self registerObservers];
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)dealloc {
|
||||||
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)loadView {
|
||||||
|
[super loadView];
|
||||||
|
|
||||||
|
self.view = [[JitsiMeetRenderingView alloc] init];
|
||||||
|
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)viewDidLoad {
|
||||||
|
[super viewDidLoad];
|
||||||
|
|
||||||
|
// Set a background color which is in accord with the JavaScript and Android
|
||||||
|
// parts of the application and causes less perceived visual flicker than
|
||||||
|
// the default background color.
|
||||||
|
self.view.backgroundColor = [UIColor colorWithRed:.07f green:.07f blue:.07f alpha:1];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)join:(JitsiMeetConferenceOptions *)options withPiP:(BOOL)enablePiP {
|
||||||
|
self.view.isPiPEnabled = enablePiP;
|
||||||
|
[self.view setProps:options == nil ? @{} : [options asProps]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)leave {
|
||||||
|
[self.view setProps:@{}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)hangUp {
|
||||||
|
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||||
|
[externalAPI sendHangUp];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setAudioMuted:(BOOL)muted {
|
||||||
|
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||||
|
[externalAPI sendSetAudioMuted:muted];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)sendEndpointTextMessage:(NSString * _Nonnull)message :(NSString * _Nullable)to {
|
||||||
|
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||||
|
[externalAPI sendEndpointTextMessage:message :to];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)toggleScreenShare:(BOOL)enabled {
|
||||||
|
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||||
|
[externalAPI toggleScreenShare:enabled];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)retrieveParticipantsInfo:(void (^ _Nonnull)(NSArray * _Nullable))completionHandler {
|
||||||
|
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||||
|
[externalAPI retrieveParticipantsInfo:completionHandler];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)openChat:(NSString*)to {
|
||||||
|
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||||
|
[externalAPI openChat:to];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)closeChat {
|
||||||
|
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||||
|
[externalAPI closeChat];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)sendChatMessage:(NSString * _Nonnull)message :(NSString * _Nullable)to {
|
||||||
|
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||||
|
[externalAPI sendChatMessage:message :to];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setVideoMuted:(BOOL)muted {
|
||||||
|
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||||
|
[externalAPI sendSetVideoMuted:muted];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark Private
|
||||||
|
|
||||||
|
- (void)registerObservers {
|
||||||
|
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleUpdateViewPropsNotification:) name:updateViewPropsNotificationName object:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)handleUpdateViewPropsNotification:(NSNotification *)notification {
|
||||||
|
NSDictionary *props = [notification.userInfo objectForKey:@"props"];
|
||||||
|
[self.view setProps:props];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
Loading…
Reference in New Issue