ios: SDK v2 pass one
- cleanup - API simplification (single loadURL method) - JitsiMeet singleton for linking helpers and globals - Linking moved to app
This commit is contained in:
parent
1c47720a08
commit
dbc88b972e
|
@ -19,11 +19,10 @@
|
||||||
#import "FIRUtilities.h"
|
#import "FIRUtilities.h"
|
||||||
#import "Types.h"
|
#import "Types.h"
|
||||||
|
|
||||||
#import <JitsiMeet/JitsiMeet.h>
|
|
||||||
|
|
||||||
@import Crashlytics;
|
@import Crashlytics;
|
||||||
@import Fabric;
|
@import Fabric;
|
||||||
@import Firebase;
|
@import Firebase;
|
||||||
|
@import JitsiMeet;
|
||||||
|
|
||||||
|
|
||||||
@implementation AppDelegate
|
@implementation AppDelegate
|
||||||
|
@ -40,10 +39,10 @@
|
||||||
|
|
||||||
// Set the conference activity type defined in this application.
|
// Set the conference activity type defined in this application.
|
||||||
// This cannot be defined by the SDK.
|
// This cannot be defined by the SDK.
|
||||||
JitsiMeetView.conferenceActivityType = JitsiMeetConferenceActivityType;
|
[JitsiMeet sharedInstance].conferenceActivityType = JitsiMeetConferenceActivityType;
|
||||||
|
[[JitsiMeet sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions];
|
||||||
|
|
||||||
return [JitsiMeetView application:application
|
return YES;
|
||||||
didFinishLaunchingWithOptions:launchOptions];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark Linking delegate methods
|
#pragma mark Linking delegate methods
|
||||||
|
@ -63,9 +62,9 @@
|
||||||
NSURL *dynamicLinkURL = dynamicLink.url;
|
NSURL *dynamicLinkURL = dynamicLink.url;
|
||||||
if (dynamicLinkURL) {
|
if (dynamicLinkURL) {
|
||||||
userActivity.webpageURL = dynamicLinkURL;
|
userActivity.webpageURL = dynamicLinkURL;
|
||||||
[JitsiMeetView application:application
|
[[JitsiMeet sharedInstance] application:application
|
||||||
continueUserActivity:userActivity
|
continueUserActivity:userActivity
|
||||||
restorationHandler:restorationHandler];
|
restorationHandler:restorationHandler];
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
@ -75,9 +74,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Default to plain old, non-Firebase-assisted Universal Links.
|
// 2. Default to plain old, non-Firebase-assisted Universal Links.
|
||||||
return [JitsiMeetView application:application
|
return [[JitsiMeet sharedInstance] application:application
|
||||||
continueUserActivity:userActivity
|
continueUserActivity:userActivity
|
||||||
restorationHandler:restorationHandler];
|
restorationHandler:restorationHandler];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)application:(UIApplication *)app
|
- (BOOL)application:(UIApplication *)app
|
||||||
|
@ -100,9 +99,9 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return [JitsiMeetView application:app
|
return [[JitsiMeet sharedInstance] application:app
|
||||||
openURL:openUrl
|
openURL:openUrl
|
||||||
options:options];
|
options:options];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright @ 2017-present Atlassian Pty Ltd
|
* Copyright @ 2018-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,18 +16,14 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import <Availability.h>
|
#import <Availability.h>
|
||||||
#import <CoreSpotlight/CoreSpotlight.h>
|
|
||||||
#import <MobileCoreServices/MobileCoreServices.h>
|
@import CoreSpotlight;
|
||||||
|
@import MobileCoreServices;
|
||||||
|
@import Intents; // Needed for NSUserActivity suggestedInvocationPhrase
|
||||||
|
|
||||||
#import "Types.h"
|
#import "Types.h"
|
||||||
#import "ViewController.h"
|
#import "ViewController.h"
|
||||||
|
|
||||||
// Needed for NSUserActivity suggestedInvocationPhrase
|
|
||||||
@import Intents;
|
|
||||||
|
|
||||||
|
|
||||||
@interface ViewController ()
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation ViewController
|
@implementation ViewController
|
||||||
|
|
||||||
|
@ -42,11 +39,9 @@
|
||||||
// anyway.
|
// anyway.
|
||||||
view.welcomePageEnabled = YES;
|
view.welcomePageEnabled = YES;
|
||||||
|
|
||||||
[view loadURL:nil];
|
[view loadURL:[[JitsiMeet sharedInstance] getInitialURL]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// JitsiMeetViewDelegate
|
// JitsiMeetViewDelegate
|
||||||
|
|
||||||
- (void)_onJitsiMeetViewDelegateEvent:(NSString *)name
|
- (void)_onJitsiMeetViewDelegateEvent:(NSString *)name
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
0B44A0191F902126009D1D64 /* MPVolumeViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0B44A0181F902126009D1D64 /* MPVolumeViewManager.m */; };
|
0B44A0191F902126009D1D64 /* MPVolumeViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0B44A0181F902126009D1D64 /* MPVolumeViewManager.m */; };
|
||||||
0B49424520AD8DBD00BD2DE0 /* outgoingStart.wav in Resources */ = {isa = PBXBuildFile; fileRef = 0B49424320AD8DBD00BD2DE0 /* outgoingStart.wav */; };
|
0B49424520AD8DBD00BD2DE0 /* outgoingStart.wav in Resources */ = {isa = PBXBuildFile; fileRef = 0B49424320AD8DBD00BD2DE0 /* outgoingStart.wav */; };
|
||||||
0B49424620AD8DBD00BD2DE0 /* outgoingRinging.wav in Resources */ = {isa = PBXBuildFile; fileRef = 0B49424420AD8DBD00BD2DE0 /* outgoingRinging.wav */; };
|
0B49424620AD8DBD00BD2DE0 /* outgoingRinging.wav in Resources */ = {isa = PBXBuildFile; fileRef = 0B49424420AD8DBD00BD2DE0 /* outgoingRinging.wav */; };
|
||||||
0B7C2CFD200F51D60060D076 /* LaunchOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 0B7C2CFC200F51D60060D076 /* LaunchOptions.m */; };
|
|
||||||
0B93EF7E1EC9DDCD0030D24D /* RCTBridgeWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B93EF7C1EC9DDCD0030D24D /* RCTBridgeWrapper.h */; };
|
0B93EF7E1EC9DDCD0030D24D /* RCTBridgeWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B93EF7C1EC9DDCD0030D24D /* RCTBridgeWrapper.h */; };
|
||||||
0B93EF7F1EC9DDCD0030D24D /* RCTBridgeWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 0B93EF7D1EC9DDCD0030D24D /* RCTBridgeWrapper.m */; };
|
0B93EF7F1EC9DDCD0030D24D /* RCTBridgeWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 0B93EF7D1EC9DDCD0030D24D /* RCTBridgeWrapper.m */; };
|
||||||
0BA13D311EE83FF8007BEF7F /* ExternalAPI.m in Sources */ = {isa = PBXBuildFile; fileRef = 0BA13D301EE83FF8007BEF7F /* ExternalAPI.m */; };
|
0BA13D311EE83FF8007BEF7F /* ExternalAPI.m in Sources */ = {isa = PBXBuildFile; fileRef = 0BA13D301EE83FF8007BEF7F /* ExternalAPI.m */; };
|
||||||
|
@ -45,6 +44,8 @@
|
||||||
C6CC49AF207412CF000DFA42 /* PiPViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6CC49AE207412CF000DFA42 /* PiPViewCoordinator.swift */; };
|
C6CC49AF207412CF000DFA42 /* PiPViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6CC49AE207412CF000DFA42 /* PiPViewCoordinator.swift */; };
|
||||||
C6F99C15204DB63E0001F710 /* JitsiMeetView+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = C6F99C13204DB63D0001F710 /* JitsiMeetView+Private.h */; };
|
C6F99C15204DB63E0001F710 /* JitsiMeetView+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = C6F99C13204DB63D0001F710 /* JitsiMeetView+Private.h */; };
|
||||||
DEFC743F21B178FA00E4DD96 /* LocaleDetector.m in Sources */ = {isa = PBXBuildFile; fileRef = DEFC743D21B178FA00E4DD96 /* LocaleDetector.m */; };
|
DEFC743F21B178FA00E4DD96 /* LocaleDetector.m in Sources */ = {isa = PBXBuildFile; fileRef = DEFC743D21B178FA00E4DD96 /* LocaleDetector.m */; };
|
||||||
|
DEFE535421FB1BF800011A3A /* JitsiMeet.m in Sources */ = {isa = PBXBuildFile; fileRef = DEFE535321FB1BF800011A3A /* JitsiMeet.m */; };
|
||||||
|
DEFE535621FB2E8300011A3A /* ReactUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = DEFE535521FB2E8300011A3A /* ReactUtils.m */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
|
@ -55,7 +56,6 @@
|
||||||
0B44A0181F902126009D1D64 /* MPVolumeViewManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MPVolumeViewManager.m; sourceTree = "<group>"; };
|
0B44A0181F902126009D1D64 /* MPVolumeViewManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MPVolumeViewManager.m; sourceTree = "<group>"; };
|
||||||
0B49424320AD8DBD00BD2DE0 /* outgoingStart.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = outgoingStart.wav; path = ../../sounds/outgoingStart.wav; sourceTree = "<group>"; };
|
0B49424320AD8DBD00BD2DE0 /* outgoingStart.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = outgoingStart.wav; path = ../../sounds/outgoingStart.wav; sourceTree = "<group>"; };
|
||||||
0B49424420AD8DBD00BD2DE0 /* outgoingRinging.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = outgoingRinging.wav; path = ../../sounds/outgoingRinging.wav; sourceTree = "<group>"; };
|
0B49424420AD8DBD00BD2DE0 /* outgoingRinging.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = outgoingRinging.wav; path = ../../sounds/outgoingRinging.wav; sourceTree = "<group>"; };
|
||||||
0B7C2CFC200F51D60060D076 /* LaunchOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LaunchOptions.m; sourceTree = "<group>"; };
|
|
||||||
0B93EF7A1EC608550030D24D /* CoreText.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreText.framework; path = System/Library/Frameworks/CoreText.framework; sourceTree = SDKROOT; };
|
0B93EF7A1EC608550030D24D /* CoreText.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreText.framework; path = System/Library/Frameworks/CoreText.framework; sourceTree = SDKROOT; };
|
||||||
0B93EF7C1EC9DDCD0030D24D /* RCTBridgeWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTBridgeWrapper.h; sourceTree = "<group>"; };
|
0B93EF7C1EC9DDCD0030D24D /* RCTBridgeWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTBridgeWrapper.h; sourceTree = "<group>"; };
|
||||||
0B93EF7D1EC9DDCD0030D24D /* RCTBridgeWrapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTBridgeWrapper.m; sourceTree = "<group>"; };
|
0B93EF7D1EC9DDCD0030D24D /* RCTBridgeWrapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTBridgeWrapper.m; sourceTree = "<group>"; };
|
||||||
|
@ -93,6 +93,10 @@
|
||||||
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>"; };
|
C6F99C13204DB63D0001F710 /* JitsiMeetView+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "JitsiMeetView+Private.h"; sourceTree = "<group>"; };
|
||||||
DEFC743D21B178FA00E4DD96 /* LocaleDetector.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LocaleDetector.m; sourceTree = "<group>"; };
|
DEFC743D21B178FA00E4DD96 /* LocaleDetector.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LocaleDetector.m; sourceTree = "<group>"; };
|
||||||
|
DEFE535321FB1BF800011A3A /* JitsiMeet.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JitsiMeet.m; sourceTree = "<group>"; };
|
||||||
|
DEFE535521FB2E8300011A3A /* ReactUtils.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ReactUtils.m; sourceTree = "<group>"; };
|
||||||
|
DEFE535721FB2E9E00011A3A /* ReactUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ReactUtils.h; sourceTree = "<group>"; };
|
||||||
|
DEFE535821FB311F00011A3A /* JitsiMeet+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "JitsiMeet+Private.h"; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
@ -158,16 +162,19 @@
|
||||||
0BA13D301EE83FF8007BEF7F /* ExternalAPI.m */,
|
0BA13D301EE83FF8007BEF7F /* ExternalAPI.m */,
|
||||||
0BD906E91EC0C00300C8C18E /* Info.plist */,
|
0BD906E91EC0C00300C8C18E /* Info.plist */,
|
||||||
0BD906E81EC0C00300C8C18E /* JitsiMeet.h */,
|
0BD906E81EC0C00300C8C18E /* JitsiMeet.h */,
|
||||||
|
DEFE535821FB311F00011A3A /* JitsiMeet+Private.h */,
|
||||||
|
DEFE535321FB1BF800011A3A /* JitsiMeet.m */,
|
||||||
0B412F161EDEC65D00B1A0A6 /* JitsiMeetView.h */,
|
0B412F161EDEC65D00B1A0A6 /* JitsiMeetView.h */,
|
||||||
0B412F171EDEC65D00B1A0A6 /* JitsiMeetView.m */,
|
0B412F171EDEC65D00B1A0A6 /* JitsiMeetView.m */,
|
||||||
C6F99C13204DB63D0001F710 /* JitsiMeetView+Private.h */,
|
C6F99C13204DB63D0001F710 /* JitsiMeetView+Private.h */,
|
||||||
0B412F1B1EDEC80100B1A0A6 /* JitsiMeetViewDelegate.h */,
|
0B412F1B1EDEC80100B1A0A6 /* JitsiMeetViewDelegate.h */,
|
||||||
0B7C2CFC200F51D60060D076 /* LaunchOptions.m */,
|
|
||||||
DEFC743D21B178FA00E4DD96 /* LocaleDetector.m */,
|
DEFC743D21B178FA00E4DD96 /* LocaleDetector.m */,
|
||||||
0B44A0181F902126009D1D64 /* MPVolumeViewManager.m */,
|
0B44A0181F902126009D1D64 /* MPVolumeViewManager.m */,
|
||||||
C6A3426B204F127900E062DD /* picture-in-picture */,
|
C6A3426B204F127900E062DD /* picture-in-picture */,
|
||||||
0BCA495D1EC4B6C600B793EE /* POSIX.m */,
|
0BCA495D1EC4B6C600B793EE /* POSIX.m */,
|
||||||
0BCA495E1EC4B6C600B793EE /* Proximity.m */,
|
0BCA495E1EC4B6C600B793EE /* Proximity.m */,
|
||||||
|
DEFE535721FB2E9E00011A3A /* ReactUtils.h */,
|
||||||
|
DEFE535521FB2E8300011A3A /* ReactUtils.m */,
|
||||||
0B93EF7C1EC9DDCD0030D24D /* RCTBridgeWrapper.h */,
|
0B93EF7C1EC9DDCD0030D24D /* RCTBridgeWrapper.h */,
|
||||||
0B93EF7D1EC9DDCD0030D24D /* RCTBridgeWrapper.m */,
|
0B93EF7D1EC9DDCD0030D24D /* RCTBridgeWrapper.m */,
|
||||||
);
|
);
|
||||||
|
@ -447,7 +454,6 @@
|
||||||
0B93EF7F1EC9DDCD0030D24D /* RCTBridgeWrapper.m in Sources */,
|
0B93EF7F1EC9DDCD0030D24D /* RCTBridgeWrapper.m in Sources */,
|
||||||
0BA13D311EE83FF8007BEF7F /* ExternalAPI.m in Sources */,
|
0BA13D311EE83FF8007BEF7F /* ExternalAPI.m in Sources */,
|
||||||
0BCA49601EC4B6C600B793EE /* POSIX.m in Sources */,
|
0BCA49601EC4B6C600B793EE /* POSIX.m in Sources */,
|
||||||
0B7C2CFD200F51D60060D076 /* LaunchOptions.m in Sources */,
|
|
||||||
C6CC49AF207412CF000DFA42 /* PiPViewCoordinator.swift in Sources */,
|
C6CC49AF207412CF000DFA42 /* PiPViewCoordinator.swift in Sources */,
|
||||||
DEFC743F21B178FA00E4DD96 /* LocaleDetector.m in Sources */,
|
DEFC743F21B178FA00E4DD96 /* LocaleDetector.m in Sources */,
|
||||||
0BCA495F1EC4B6C600B793EE /* AudioMode.m in Sources */,
|
0BCA495F1EC4B6C600B793EE /* AudioMode.m in Sources */,
|
||||||
|
@ -455,11 +461,13 @@
|
||||||
0BCA49611EC4B6C600B793EE /* Proximity.m in Sources */,
|
0BCA49611EC4B6C600B793EE /* Proximity.m in Sources */,
|
||||||
A480429C21EE335600289B73 /* AmplitudeModule.m in Sources */,
|
A480429C21EE335600289B73 /* AmplitudeModule.m in Sources */,
|
||||||
C69EFA0C209A0F660027712B /* JMCallKitEmitter.swift in Sources */,
|
C69EFA0C209A0F660027712B /* JMCallKitEmitter.swift in Sources */,
|
||||||
|
DEFE535621FB2E8300011A3A /* ReactUtils.m in Sources */,
|
||||||
C6A34261204EF76800E062DD /* DragGestureController.swift in Sources */,
|
C6A34261204EF76800E062DD /* DragGestureController.swift in Sources */,
|
||||||
A4A934E9212F3ADB001E9388 /* Dropbox.m in Sources */,
|
A4A934E9212F3ADB001E9388 /* Dropbox.m in Sources */,
|
||||||
C69EFA0D209A0F660027712B /* JMCallKitProxy.swift in Sources */,
|
C69EFA0D209A0F660027712B /* JMCallKitProxy.swift in Sources */,
|
||||||
C69EFA0E209A0F660027712B /* JMCallKitListener.swift in Sources */,
|
C69EFA0E209A0F660027712B /* JMCallKitListener.swift in Sources */,
|
||||||
0B412F191EDEC65D00B1A0A6 /* JitsiMeetView.m in Sources */,
|
0B412F191EDEC65D00B1A0A6 /* JitsiMeetView.m in Sources */,
|
||||||
|
DEFE535421FB1BF800011A3A /* JitsiMeet.m in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Copyright @ 2019-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 "JitsiMeet.h"
|
||||||
|
|
||||||
|
@interface JitsiMeet ()
|
||||||
|
|
||||||
|
- (RCTBridge *)getReactBridge;
|
||||||
|
|
||||||
|
@end
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright @ 2017-present Atlassian Pty Ltd
|
* Copyright @ 2018-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.
|
||||||
|
@ -14,6 +15,32 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// JitsiMeetView
|
|
||||||
#import <JitsiMeet/JitsiMeetView.h>
|
#import <JitsiMeet/JitsiMeetView.h>
|
||||||
#import <JitsiMeet/JitsiMeetViewDelegate.h>
|
#import <JitsiMeet/JitsiMeetViewDelegate.h>
|
||||||
|
|
||||||
|
@interface JitsiMeet : NSObject
|
||||||
|
|
||||||
|
@property (copy, nonatomic, nullable) NSString *conferenceActivityType;
|
||||||
|
|
||||||
|
#pragma mak - This class is a singleton
|
||||||
|
|
||||||
|
+ (instancetype)sharedInstance;
|
||||||
|
|
||||||
|
#pragma mark - Methods that the App delegate must call
|
||||||
|
|
||||||
|
- (BOOL)application:(UIApplication *_Nonnull)application
|
||||||
|
didFinishLaunchingWithOptions:(NSDictionary *_Nonnull)launchOptions;
|
||||||
|
|
||||||
|
- (BOOL)application:(UIApplication * _Nonnull)application
|
||||||
|
continueUserActivity:(NSUserActivity * _Nonnull)userActivity
|
||||||
|
restorationHandler:(void (^ _Nullable)(NSArray * _Nullable))restorationHandler;
|
||||||
|
|
||||||
|
- (BOOL)application:(UIApplication *)app
|
||||||
|
openURL:(NSURL *)url
|
||||||
|
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options;
|
||||||
|
|
||||||
|
#pragma mark - Utility methods
|
||||||
|
|
||||||
|
- (NSDictionary *)getInitialURL;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
|
@ -0,0 +1,161 @@
|
||||||
|
/*
|
||||||
|
* Copyright @ 2019-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 <Intents/Intents.h>
|
||||||
|
|
||||||
|
#import "Dropbox.h"
|
||||||
|
#import "JitsiMeet+Private.h"
|
||||||
|
#import "JitsiMeetView+Private.h"
|
||||||
|
#import "RCTBridgeWrapper.h"
|
||||||
|
#import "ReactUtils.h"
|
||||||
|
|
||||||
|
#import <RNGoogleSignin/RNGoogleSignin.h>
|
||||||
|
|
||||||
|
|
||||||
|
@implementation JitsiMeet {
|
||||||
|
RCTBridgeWrapper *_bridgeWrapper;
|
||||||
|
NSDictionary *_launchOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mak - This class is a singleton
|
||||||
|
|
||||||
|
+ (instancetype)sharedInstance {
|
||||||
|
static JitsiMeet *sharedInstance = nil;
|
||||||
|
static dispatch_once_t onceToken;
|
||||||
|
|
||||||
|
dispatch_once(&onceToken, ^{
|
||||||
|
sharedInstance = [[self alloc] init];
|
||||||
|
});
|
||||||
|
|
||||||
|
return sharedInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)init {
|
||||||
|
if (self = [super init]) {
|
||||||
|
// Initialize the on and only bridge for interfacing with React Native.
|
||||||
|
_bridgeWrapper = [[RCTBridgeWrapper alloc] init];
|
||||||
|
|
||||||
|
// Register a fatal error handler for React.
|
||||||
|
registerReactFatalErrorHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Methods that the App delegate must call
|
||||||
|
|
||||||
|
- (BOOL)application:(UIApplication *)application
|
||||||
|
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||||
|
|
||||||
|
_launchOptions = [launchOptions copy];
|
||||||
|
|
||||||
|
[Dropbox setAppKey];
|
||||||
|
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)application:(UIApplication *)application
|
||||||
|
continueUserActivity:(NSUserActivity *)userActivity
|
||||||
|
restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler {
|
||||||
|
|
||||||
|
id url = [self urlFromUserActivity:userActivity];
|
||||||
|
|
||||||
|
return url && [JitsiMeetView loadURLInViews:url];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)application:(UIApplication *)app
|
||||||
|
openURL:(NSURL *)url
|
||||||
|
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
|
||||||
|
|
||||||
|
if ([Dropbox application:app openURL:url options:options]) {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([RNGoogleSignin application:app
|
||||||
|
openURL:url
|
||||||
|
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
|
||||||
|
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]]) {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [JitsiMeetView loadURLInViews:@{ @"url" : url.absoluteString }];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Utility methods
|
||||||
|
|
||||||
|
- (NSDictionary *)getInitialURL {
|
||||||
|
if (_launchOptions[UIApplicationLaunchOptionsURLKey]) {
|
||||||
|
NSURL *url = _launchOptions[UIApplicationLaunchOptionsURLKey];
|
||||||
|
return @{ @"url" : url.absoluteString };
|
||||||
|
} else {
|
||||||
|
NSDictionary *userActivityDictionary
|
||||||
|
= _launchOptions[UIApplicationLaunchOptionsUserActivityDictionaryKey];
|
||||||
|
NSUserActivity *userActivity
|
||||||
|
= [userActivityDictionary objectForKey:@"UIApplicationLaunchOptionsUserActivityKey"];
|
||||||
|
if (userActivity != nil) {
|
||||||
|
return [self urlFromUserActivity:userActivity];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSDictionary *)urlFromUserActivity:(NSUserActivity *)userActivity {
|
||||||
|
NSString *activityType = userActivity.activityType;
|
||||||
|
|
||||||
|
if ([activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
|
||||||
|
// App was started by opening a URL in the browser
|
||||||
|
return @{ @"url" : userActivity.webpageURL.absoluteString };
|
||||||
|
} else if ([activityType isEqualToString:@"INStartAudioCallIntent"]
|
||||||
|
|| [activityType isEqualToString:@"INStartVideoCallIntent"]) {
|
||||||
|
// App was started by a CallKit Intent
|
||||||
|
INIntent *intent = userActivity.interaction.intent;
|
||||||
|
NSArray<INPerson *> *contacts;
|
||||||
|
NSString *url;
|
||||||
|
BOOL startAudioOnly = NO;
|
||||||
|
|
||||||
|
if ([intent isKindOfClass:[INStartAudioCallIntent class]]) {
|
||||||
|
contacts = ((INStartAudioCallIntent *) intent).contacts;
|
||||||
|
startAudioOnly = YES;
|
||||||
|
} else if ([intent isKindOfClass:[INStartVideoCallIntent class]]) {
|
||||||
|
contacts = ((INStartVideoCallIntent *) intent).contacts;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contacts && (url = contacts.firstObject.personHandle.value)) {
|
||||||
|
return @{
|
||||||
|
@"config": @{@"startAudioOnly":@(startAudioOnly)},
|
||||||
|
@"url": url
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else if (self.conferenceActivityType && [activityType isEqualToString:self.conferenceActivityType]) {
|
||||||
|
// App was started by continuing a registered NSUserActivity (SiriKit, Handoff, ...)
|
||||||
|
NSString *url;
|
||||||
|
|
||||||
|
if ((url = userActivity.userInfo[@"url"])) {
|
||||||
|
return @{ @"url" : url };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - Private API methods
|
||||||
|
|
||||||
|
- (RCTBridge *)getReactBridge {
|
||||||
|
return _bridgeWrapper.bridge;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright @ 2017-present Atlassian Pty Ltd
|
* Copyright @ 2018-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.
|
||||||
|
@ -18,7 +19,7 @@
|
||||||
|
|
||||||
@interface JitsiMeetView ()
|
@interface JitsiMeetView ()
|
||||||
|
|
||||||
+ (NSDictionary *)conferenceURLFromUserActivity:(NSUserActivity *)userActivity;
|
|
||||||
+ (instancetype)viewForExternalAPIScope:(NSString *)externalAPIScope;
|
+ (instancetype)viewForExternalAPIScope:(NSString *)externalAPIScope;
|
||||||
|
+ (BOOL)loadURLInViews:(NSDictionary *)urlObject;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright @ 2017-present Atlassian Pty Ltd
|
* Copyright @ 2018-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.
|
||||||
|
@ -33,26 +34,6 @@
|
||||||
|
|
||||||
@property (nonatomic) BOOL welcomePageEnabled;
|
@property (nonatomic) BOOL welcomePageEnabled;
|
||||||
|
|
||||||
+ (BOOL)application:(UIApplication *_Nonnull)application
|
- (void)loadURL:(NSDictionary * _Nullable)urlObject;
|
||||||
didFinishLaunchingWithOptions:(NSDictionary *_Nonnull)launchOptions;
|
|
||||||
|
|
||||||
+ (BOOL)application:(UIApplication * _Nonnull)application
|
|
||||||
continueUserActivity:(NSUserActivity * _Nonnull)userActivity
|
|
||||||
restorationHandler:(void (^ _Nullable)(NSArray * _Nullable))restorationHandler;
|
|
||||||
|
|
||||||
+ (BOOL)application:(UIApplication *)app
|
|
||||||
openURL:(NSURL *)url
|
|
||||||
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options;
|
|
||||||
|
|
||||||
+ (BOOL)application:(UIApplication * _Nonnull)application
|
|
||||||
openURL:(NSURL * _Nonnull)URL
|
|
||||||
sourceApplication:(NSString * _Nullable)sourceApplication
|
|
||||||
annotation:(id _Nullable)annotation __deprecated;
|
|
||||||
|
|
||||||
- (void)loadURL:(NSURL * _Nullable)url;
|
|
||||||
|
|
||||||
- (void)loadURLObject:(NSDictionary * _Nullable)urlObject;
|
|
||||||
|
|
||||||
- (void)loadURLString:(NSString * _Nullable)urlString;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright @ 2017-present Atlassian Pty Ltd
|
* Copyright @ 2018-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.
|
||||||
|
@ -14,62 +15,15 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#import <Intents/Intents.h>
|
|
||||||
|
|
||||||
#include <mach/mach_time.h>
|
#include <mach/mach_time.h>
|
||||||
|
|
||||||
#import <React/RCTAssert.h>
|
|
||||||
#import <React/RCTLinkingManager.h>
|
|
||||||
#import <React/RCTRootView.h>
|
#import <React/RCTRootView.h>
|
||||||
|
|
||||||
#import <RNGoogleSignin/RNGoogleSignin.h>
|
#import "JitsiMeet+Private.h"
|
||||||
|
|
||||||
#import "Dropbox.h"
|
|
||||||
#import "JitsiMeetView+Private.h"
|
#import "JitsiMeetView+Private.h"
|
||||||
#import "RCTBridgeWrapper.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A `RCTFatalHandler` implementation which swallows JavaScript errors. In the
|
|
||||||
* Release configuration, React Native will (intentionally) raise an unhandled
|
|
||||||
* `NSException` for an unhandled JavaScript error. This will effectively kill
|
|
||||||
* the application. `_RCTFatal` is suitable to be in accord with the Web i.e.
|
|
||||||
* not kill the application.
|
|
||||||
*/
|
|
||||||
RCTFatalHandler _RCTFatal = ^(NSError *error) {
|
|
||||||
id jsStackTrace = error.userInfo[RCTJSStackTraceKey];
|
|
||||||
@try {
|
|
||||||
NSString *name
|
|
||||||
= [NSString stringWithFormat:@"%@: %@",
|
|
||||||
RCTFatalExceptionName,
|
|
||||||
error.localizedDescription];
|
|
||||||
NSString *message
|
|
||||||
= RCTFormatError(error.localizedDescription, jsStackTrace, 75);
|
|
||||||
[NSException raise:name format:@"%@", message];
|
|
||||||
} @catch (NSException *e) {
|
|
||||||
if (!jsStackTrace) {
|
|
||||||
@throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
@implementation JitsiMeetView {
|
||||||
* Helper function to register a fatal error handler for React. Our handler
|
|
||||||
* won't kill the process, it will swallow JS errors and print stack traces
|
|
||||||
* instead.
|
|
||||||
*/
|
|
||||||
void registerFatalErrorHandler() {
|
|
||||||
#if !DEBUG
|
|
||||||
// In the Release configuration, React Native will (intentionally) raise an
|
|
||||||
// unhandled `NSException` for an unhandled JavaScript error. This will
|
|
||||||
// effectively kill the application. In accord with the Web, do not kill the
|
|
||||||
// application.
|
|
||||||
if (!RCTGetFatalHandler()) {
|
|
||||||
RCTSetFatalHandler(_RCTFatal);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
@interface JitsiMeetView() {
|
|
||||||
/**
|
/**
|
||||||
* The unique identifier of this `JitsiMeetView` within the process for the
|
* The unique identifier of this `JitsiMeetView` within the process for the
|
||||||
* purposes of `ExternalAPI`. The name scope was inspired by postis which we
|
* purposes of `ExternalAPI`. The name scope was inspired by postis which we
|
||||||
|
@ -78,98 +32,24 @@ void registerFatalErrorHandler() {
|
||||||
NSString *externalAPIScope;
|
NSString *externalAPIScope;
|
||||||
|
|
||||||
RCTRootView *rootView;
|
RCTRootView *rootView;
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation JitsiMeetView {
|
|
||||||
NSNumber *_pictureInPictureEnabled;
|
NSNumber *_pictureInPictureEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
@dynamic pictureInPictureEnabled;
|
@dynamic pictureInPictureEnabled;
|
||||||
|
|
||||||
static NSString *_conferenceActivityType;
|
|
||||||
|
|
||||||
static RCTBridgeWrapper *bridgeWrapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy of the `launchOptions` dictionary that the application was started with.
|
|
||||||
* It is required for the initial URL to be used if a (Universal) link was used
|
|
||||||
* to launch a new instance of the application.
|
|
||||||
*/
|
|
||||||
static NSDictionary *_launchOptions;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The `JitsiMeetView`s associated with their `ExternalAPI` scopes (i.e. unique
|
* The `JitsiMeetView`s associated with their `ExternalAPI` scopes (i.e. unique
|
||||||
* identifiers within the process).
|
* identifiers within the process).
|
||||||
*/
|
*/
|
||||||
static NSMapTable<NSString *, JitsiMeetView *> *views;
|
static NSMapTable<NSString *, JitsiMeetView *> *views;
|
||||||
|
|
||||||
+ (BOOL)application:(UIApplication *)application
|
/**
|
||||||
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
* This gets called automagically when the program starts.
|
||||||
// Store launch options, will be used when we create the bridge.
|
*/
|
||||||
_launchOptions = [launchOptions copy];
|
__attribute__((constructor))
|
||||||
|
static void initializeViewsMap() {
|
||||||
[Dropbox setAppKey];
|
views = [NSMapTable strongToWeakObjectsMapTable];
|
||||||
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark Linking delegate helpers
|
|
||||||
// https://facebook.github.io/react-native/docs/linking.html
|
|
||||||
|
|
||||||
+ (BOOL)application:(UIApplication *)application
|
|
||||||
continueUserActivity:(NSUserActivity *)userActivity
|
|
||||||
restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler
|
|
||||||
{
|
|
||||||
// XXX At least twice we received bug reports about malfunctioning loadURL
|
|
||||||
// in the Jitsi Meet SDK while the Jitsi Meet app seemed to functioning as
|
|
||||||
// expected in our testing. But that was to be expected because the app does
|
|
||||||
// not exercise loadURL. In order to increase the test coverage of loadURL,
|
|
||||||
// channel Universal linking through loadURL.
|
|
||||||
|
|
||||||
id url = [self conferenceURLFromUserActivity:userActivity];
|
|
||||||
|
|
||||||
if (url && [self loadURLObjectInViews:url]) {
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
return [RCTLinkingManager application:application
|
|
||||||
continueUserActivity:userActivity
|
|
||||||
restorationHandler:restorationHandler];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (BOOL)application:(UIApplication *)app
|
|
||||||
openURL:(NSURL *)url
|
|
||||||
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
|
|
||||||
if ([Dropbox application:app openURL:url options:options]) {
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ([RNGoogleSignin application:app
|
|
||||||
openURL:url
|
|
||||||
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
|
|
||||||
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]]) {
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX At least twice we received bug reports about malfunctioning loadURL
|
|
||||||
// in the Jitsi Meet SDK while the Jitsi Meet app seemed to functioning as
|
|
||||||
// expected in our testing. But that was to be expected because the app does
|
|
||||||
// not exercise loadURL. In order to increase the test coverage of loadURL,
|
|
||||||
// channel Universal linking through loadURL.
|
|
||||||
if ([self loadURLInViews:url]) {
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
return [RCTLinkingManager application:app openURL:url options:options];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (BOOL)application:(UIApplication *)application
|
|
||||||
openURL:(NSURL *)url
|
|
||||||
sourceApplication:(NSString *)sourceApplication
|
|
||||||
annotation:(id)annotation {
|
|
||||||
return [self application:application openURL:url options:@{}];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark Initializers
|
#pragma mark Initializers
|
||||||
|
@ -201,19 +81,26 @@ static NSMapTable<NSString *, JitsiMeetView *> *views;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark API
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads a specific `NSURL` which may identify a conference to join. If the
|
* Internal initialization:
|
||||||
* specified `NSURL` is `nil` and the Welcome page is enabled, the Welcome page
|
|
||||||
* is displayed instead.
|
|
||||||
*
|
*
|
||||||
* @param url The `NSURL` to load which may identify a conference to join.
|
* - sets the background color
|
||||||
|
* - initializes the external API scope
|
||||||
*/
|
*/
|
||||||
- (void)loadURL:(NSURL *)url {
|
- (void)initWithXXX {
|
||||||
[self loadURLString:url ? url.absoluteString : nil];
|
// Hook this JitsiMeetView into ExternalAPI.
|
||||||
|
externalAPIScope = [NSUUID UUID].UUIDString;
|
||||||
|
[views setObject:self forKey:externalAPIScope];
|
||||||
|
|
||||||
|
// 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.backgroundColor
|
||||||
|
= [UIColor colorWithRed:.07f green:.07f blue:.07f alpha:1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark API
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads a specific URL which may identify a conference to join. The URL is
|
* Loads a specific URL which may identify a conference to join. The URL is
|
||||||
* specified in the form of an `NSDictionary` of properties which (1)
|
* specified in the form of an `NSDictionary` of properties which (1)
|
||||||
|
@ -224,7 +111,7 @@ static NSMapTable<NSString *, JitsiMeetView *> *views;
|
||||||
*
|
*
|
||||||
* @param urlObject The URL to load which may identify a conference to join.
|
* @param urlObject The URL to load which may identify a conference to join.
|
||||||
*/
|
*/
|
||||||
- (void)loadURLObject:(NSDictionary *)urlObject {
|
- (void)loadURL:(NSDictionary *_Nullable)urlObject {
|
||||||
NSMutableDictionary *props = [[NSMutableDictionary alloc] init];
|
NSMutableDictionary *props = [[NSMutableDictionary alloc] init];
|
||||||
|
|
||||||
if (self.defaultURL) {
|
if (self.defaultURL) {
|
||||||
|
@ -242,14 +129,14 @@ static NSMapTable<NSString *, JitsiMeetView *> *views;
|
||||||
props[@"url"] = urlObject;
|
props[@"url"] = urlObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX The method loadURLObject: is supposed to be imperative i.e. a second
|
// XXX The method loadURL: is supposed to be imperative i.e. a second
|
||||||
// invocation with one and the same URL is expected to join the respective
|
// 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 again if the first invocation was followed by leaving the
|
||||||
// conference. However, React and, respectively,
|
// conference. However, React and, respectively,
|
||||||
// appProperties/initialProperties are declarative expressions i.e. one and
|
// appProperties/initialProperties are declarative expressions i.e. one and
|
||||||
// the same URL will not trigger an automatic re-render in the JavaScript
|
// the same URL will not trigger an automatic re-render in the JavaScript
|
||||||
// source code. The workaround implemented bellow introduces imperativeness
|
// source code. The workaround implemented bellow introduces imperativeness
|
||||||
// in React Component props by defining a unique value per loadURLObject:
|
// in React Component props by defining a unique value per loadURL:
|
||||||
// invocation.
|
// invocation.
|
||||||
props[@"timestamp"] = @(mach_absolute_time());
|
props[@"timestamp"] = @(mach_absolute_time());
|
||||||
|
|
||||||
|
@ -257,8 +144,9 @@ static NSMapTable<NSString *, JitsiMeetView *> *views;
|
||||||
// Update props with the new URL.
|
// Update props with the new URL.
|
||||||
rootView.appProperties = props;
|
rootView.appProperties = props;
|
||||||
} else {
|
} else {
|
||||||
|
RCTBridge *bridge = [[JitsiMeet sharedInstance] getReactBridge];
|
||||||
rootView
|
rootView
|
||||||
= [[RCTRootView alloc] initWithBridge:bridgeWrapper.bridge
|
= [[RCTRootView alloc] initWithBridge:bridge
|
||||||
moduleName:@"App"
|
moduleName:@"App"
|
||||||
initialProperties:props];
|
initialProperties:props];
|
||||||
rootView.backgroundColor = self.backgroundColor;
|
rootView.backgroundColor = self.backgroundColor;
|
||||||
|
@ -272,28 +160,6 @@ static NSMapTable<NSString *, JitsiMeetView *> *views;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads a specific URL `NSString` which may identify a conference to
|
|
||||||
* join. If the specified URL `NSString` is `nil` and the Welcome page is
|
|
||||||
* enabled, the Welcome page is displayed instead.
|
|
||||||
*
|
|
||||||
* @param urlString The URL `NSString` to load which may identify a conference
|
|
||||||
* to join.
|
|
||||||
*/
|
|
||||||
- (void)loadURLString:(NSString *)urlString {
|
|
||||||
[self loadURLObject:urlString ? @{ @"url": urlString } : nil];
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma conferenceActivityType getter / setter
|
|
||||||
|
|
||||||
+ (NSString *)conferenceActivityType {
|
|
||||||
return _conferenceActivityType;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (void) setConferenceActivityType:(NSString *)conferenceActivityType {
|
|
||||||
_conferenceActivityType = conferenceActivityType;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma pictureInPictureEnabled getter / setter
|
#pragma pictureInPictureEnabled getter / setter
|
||||||
|
|
||||||
- (void) setPictureInPictureEnabled:(BOOL)pictureInPictureEnabled {
|
- (void) setPictureInPictureEnabled:(BOOL)pictureInPictureEnabled {
|
||||||
|
@ -318,19 +184,7 @@ static NSMapTable<NSString *, JitsiMeetView *> *views;
|
||||||
|
|
||||||
#pragma mark Private methods
|
#pragma mark Private methods
|
||||||
|
|
||||||
/**
|
+ (BOOL)loadURLInViews:(NSDictionary *)urlObject {
|
||||||
* Loads a specific `NSURL` in all existing `JitsiMeetView`s.
|
|
||||||
*
|
|
||||||
* @param url The `NSURL` to load in all existing `JitsiMeetView`s.
|
|
||||||
* @return `YES` if the specified `url` was submitted for loading in at least
|
|
||||||
* one `JitsiMeetView`; otherwise, `NO`.
|
|
||||||
*/
|
|
||||||
+ (BOOL)loadURLInViews:(NSURL *)url {
|
|
||||||
return
|
|
||||||
[self loadURLObjectInViews:url ? @{ @"url": url.absoluteString } : nil];
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (BOOL)loadURLObjectInViews:(NSDictionary *)urlObject {
|
|
||||||
BOOL handled = NO;
|
BOOL handled = NO;
|
||||||
|
|
||||||
if (views) {
|
if (views) {
|
||||||
|
@ -339,7 +193,7 @@ static NSMapTable<NSString *, JitsiMeetView *> *views;
|
||||||
= [self viewForExternalAPIScope:externalAPIScope];
|
= [self viewForExternalAPIScope:externalAPIScope];
|
||||||
|
|
||||||
if (view) {
|
if (view) {
|
||||||
[view loadURLObject:urlObject];
|
[view loadURL:urlObject];
|
||||||
handled = YES;
|
handled = YES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -348,79 +202,8 @@ static NSMapTable<NSString *, JitsiMeetView *> *views;
|
||||||
return handled;
|
return handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (NSDictionary *)conferenceURLFromUserActivity:(NSUserActivity *)userActivity {
|
|
||||||
NSString *activityType = userActivity.activityType;
|
|
||||||
|
|
||||||
if ([activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
|
|
||||||
// App was started by opening a URL in the browser
|
|
||||||
return @{ @"url" : userActivity.webpageURL.absoluteString };
|
|
||||||
} else if ([activityType isEqualToString:@"INStartAudioCallIntent"]
|
|
||||||
|| [activityType isEqualToString:@"INStartVideoCallIntent"]) {
|
|
||||||
// App was started by a CallKit Intent
|
|
||||||
INIntent *intent = userActivity.interaction.intent;
|
|
||||||
NSArray<INPerson *> *contacts;
|
|
||||||
NSString *url;
|
|
||||||
BOOL startAudioOnly = NO;
|
|
||||||
|
|
||||||
if ([intent isKindOfClass:[INStartAudioCallIntent class]]) {
|
|
||||||
contacts = ((INStartAudioCallIntent *) intent).contacts;
|
|
||||||
startAudioOnly = YES;
|
|
||||||
} else if ([intent isKindOfClass:[INStartVideoCallIntent class]]) {
|
|
||||||
contacts = ((INStartVideoCallIntent *) intent).contacts;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (contacts && (url = contacts.firstObject.personHandle.value)) {
|
|
||||||
return @{
|
|
||||||
@"config": @{@"startAudioOnly":@(startAudioOnly)},
|
|
||||||
@"url": url
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} else if (_conferenceActivityType && [activityType isEqualToString:_conferenceActivityType]) {
|
|
||||||
// App was started by continuing a registered NSUserActivity (SiriKit, Handoff, ...)
|
|
||||||
NSString *url;
|
|
||||||
|
|
||||||
if ((url = userActivity.userInfo[@"url"])) {
|
|
||||||
return @{ @"url" : url };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (instancetype)viewForExternalAPIScope:(NSString *)externalAPIScope {
|
+ (instancetype)viewForExternalAPIScope:(NSString *)externalAPIScope {
|
||||||
return [views objectForKey:externalAPIScope];
|
return [views objectForKey:externalAPIScope];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal initialization:
|
|
||||||
*
|
|
||||||
* - sets the background color
|
|
||||||
* - creates the React bridge
|
|
||||||
* - loads the necessary custom fonts
|
|
||||||
* - registers a custom fatal error error handler for React
|
|
||||||
*/
|
|
||||||
- (void)initWithXXX {
|
|
||||||
static dispatch_once_t dispatchOncePredicate;
|
|
||||||
|
|
||||||
dispatch_once(&dispatchOncePredicate, ^{
|
|
||||||
// Initialize the static state of JitsiMeetView.
|
|
||||||
bridgeWrapper
|
|
||||||
= [[RCTBridgeWrapper alloc] initWithLaunchOptions:_launchOptions];
|
|
||||||
views = [NSMapTable strongToWeakObjectsMapTable];
|
|
||||||
|
|
||||||
// Register a fatal error handler for React.
|
|
||||||
registerFatalErrorHandler();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Hook this JitsiMeetView into ExternalAPI.
|
|
||||||
externalAPIScope = [NSUUID UUID].UUIDString;
|
|
||||||
[views setObject:self forKey:externalAPIScope];
|
|
||||||
|
|
||||||
// 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.backgroundColor
|
|
||||||
= [UIColor colorWithRed:.07f green:.07f blue:.07f alpha:1];
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright @ 2018-present Atlassian Pty Ltd
|
|
||||||
*
|
|
||||||
* 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"
|
|
||||||
|
|
||||||
#import <React/RCTBridge.h>
|
|
||||||
#import <React/RCTBridgeModule.h>
|
|
||||||
|
|
||||||
@interface LaunchOptions : NSObject<RCTBridgeModule>
|
|
||||||
|
|
||||||
@property (nonatomic, weak) RCTBridge *bridge;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation LaunchOptions
|
|
||||||
|
|
||||||
RCT_EXPORT_MODULE();
|
|
||||||
|
|
||||||
- (dispatch_queue_t)methodQueue {
|
|
||||||
return dispatch_get_main_queue();
|
|
||||||
}
|
|
||||||
|
|
||||||
RCT_EXPORT_METHOD(getInitialURL:(RCTPromiseResolveBlock)resolve
|
|
||||||
reject:(__unused RCTPromiseRejectBlock)reject) {
|
|
||||||
id initialURL = nil;
|
|
||||||
|
|
||||||
if (self.bridge.launchOptions[UIApplicationLaunchOptionsURLKey]) {
|
|
||||||
NSURL *url = self.bridge.launchOptions[UIApplicationLaunchOptionsURLKey];
|
|
||||||
initialURL = url.absoluteString;
|
|
||||||
} else {
|
|
||||||
NSDictionary *userActivityDictionary
|
|
||||||
= self.bridge.launchOptions[UIApplicationLaunchOptionsUserActivityDictionaryKey];
|
|
||||||
NSUserActivity *userActivity
|
|
||||||
= [userActivityDictionary objectForKey:@"UIApplicationLaunchOptionsUserActivityKey"];
|
|
||||||
if (userActivity != nil) {
|
|
||||||
initialURL = [JitsiMeetView conferenceURLFromUserActivity:userActivity];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resolve(initialURL != nil ? initialURL : (id)kCFNull);
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
|
@ -34,6 +34,4 @@
|
||||||
|
|
||||||
@property (nonatomic, readonly, strong) RCTBridge *bridge;
|
@property (nonatomic, readonly, strong) RCTBridge *bridge;
|
||||||
|
|
||||||
- (instancetype)initWithLaunchOptions:(NSDictionary *)launchOptions;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -22,12 +22,12 @@
|
||||||
*/
|
*/
|
||||||
@implementation RCTBridgeWrapper
|
@implementation RCTBridgeWrapper
|
||||||
|
|
||||||
- (instancetype)initWithLaunchOptions:(NSDictionary *)launchOptions {
|
- (instancetype)init {
|
||||||
self = [super init];
|
self = [super init];
|
||||||
if (self) {
|
if (self) {
|
||||||
_bridge
|
_bridge
|
||||||
= [[RCTBridge alloc] initWithDelegate:self
|
= [[RCTBridge alloc] initWithDelegate:self
|
||||||
launchOptions:launchOptions];
|
launchOptions:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* Copyright @ 2019-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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ReactUtils_h
|
||||||
|
#define ReactUtils_h
|
||||||
|
|
||||||
|
void registerReactFatalErrorHandler(void);
|
||||||
|
|
||||||
|
#endif /* ReactUtils_h */
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* Copyright @ 2019-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 <React/RCTAssert.h>
|
||||||
|
|
||||||
|
#import "ReactUtils.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A `RCTFatalHandler` implementation which swallows JavaScript errors. In the
|
||||||
|
* Release configuration, React Native will (intentionally) raise an unhandled
|
||||||
|
* `NSException` for an unhandled JavaScript error. This will effectively kill
|
||||||
|
* the application. `_RCTFatal` is suitable to be in accord with the Web i.e.
|
||||||
|
* not kill the application.
|
||||||
|
*/
|
||||||
|
RCTFatalHandler _RCTFatal = ^(NSError *error) {
|
||||||
|
id jsStackTrace = error.userInfo[RCTJSStackTraceKey];
|
||||||
|
@try {
|
||||||
|
NSString *name
|
||||||
|
= [NSString stringWithFormat:@"%@: %@",
|
||||||
|
RCTFatalExceptionName,
|
||||||
|
error.localizedDescription];
|
||||||
|
NSString *message
|
||||||
|
= RCTFormatError(error.localizedDescription, jsStackTrace, 75);
|
||||||
|
[NSException raise:name format:@"%@", message];
|
||||||
|
} @catch (NSException *e) {
|
||||||
|
if (!jsStackTrace) {
|
||||||
|
@throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to register a fatal error handler for React. Our handler
|
||||||
|
* won't kill the process, it will swallow JS errors and print stack traces
|
||||||
|
* instead.
|
||||||
|
*/
|
||||||
|
void registerReactFatalErrorHandler() {
|
||||||
|
#if !DEBUG
|
||||||
|
// In the Release configuration, React Native will (intentionally) raise an
|
||||||
|
// unhandled `NSException` for an unhandled JavaScript error. This will
|
||||||
|
// effectively kill the application. In accord with the Web, do not kill the
|
||||||
|
// application.
|
||||||
|
if (!RCTGetFatalHandler()) {
|
||||||
|
RCTSetFatalHandler(_RCTFatal);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
Loading…
Reference in New Issue