Implement Jitsi meet presentation interface that supports custom PiP solution
This commit is contained in:
parent
181580871f
commit
f8163de765
|
@ -7,8 +7,9 @@
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
C6245F57205044120040BE68 /* JitsiMeet.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C6F99C4F204DE79F0001F710 /* JitsiMeet.framework */; };
|
||||||
|
C6245F58205044150040BE68 /* WebRTC.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C6A34247204DF18000E062DD /* WebRTC.framework */; };
|
||||||
C6A34249204DF18000E062DD /* WebRTC.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C6A34247204DF18000E062DD /* WebRTC.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
C6A34249204DF18000E062DD /* WebRTC.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = C6A34247204DF18000E062DD /* WebRTC.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||||
C6A3424C204DF98E00E062DD /* JitsiViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6A3424B204DF98E00E062DD /* JitsiViewController.swift */; };
|
|
||||||
C6F99C3B204DE6BE0001F710 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6F99C3A204DE6BE0001F710 /* AppDelegate.swift */; };
|
C6F99C3B204DE6BE0001F710 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6F99C3A204DE6BE0001F710 /* AppDelegate.swift */; };
|
||||||
C6F99C3D204DE6BE0001F710 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6F99C3C204DE6BE0001F710 /* ViewController.swift */; };
|
C6F99C3D204DE6BE0001F710 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6F99C3C204DE6BE0001F710 /* ViewController.swift */; };
|
||||||
C6F99C40204DE6BE0001F710 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C6F99C3E204DE6BE0001F710 /* Main.storyboard */; };
|
C6F99C40204DE6BE0001F710 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C6F99C3E204DE6BE0001F710 /* Main.storyboard */; };
|
||||||
|
@ -34,7 +35,6 @@
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
C6A34247204DF18000E062DD /* WebRTC.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebRTC.framework; path = "../../node_modules/react-native-webrtc/ios/WebRTC.framework"; sourceTree = "<group>"; };
|
C6A34247204DF18000E062DD /* WebRTC.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebRTC.framework; path = "../../node_modules/react-native-webrtc/ios/WebRTC.framework"; sourceTree = "<group>"; };
|
||||||
C6A3424B204DF98E00E062DD /* JitsiViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JitsiViewController.swift; sourceTree = "<group>"; };
|
|
||||||
C6F99C37204DE6BE0001F710 /* PiPApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PiPApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
C6F99C37204DE6BE0001F710 /* PiPApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PiPApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
C6F99C3A204DE6BE0001F710 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
C6F99C3A204DE6BE0001F710 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||||
C6F99C3C204DE6BE0001F710 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
|
C6F99C3C204DE6BE0001F710 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
|
||||||
|
@ -50,6 +50,8 @@
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
C6245F57205044120040BE68 /* JitsiMeet.framework in Frameworks */,
|
||||||
|
C6245F58205044150040BE68 /* WebRTC.framework in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
@ -78,7 +80,6 @@
|
||||||
children = (
|
children = (
|
||||||
C6F99C3A204DE6BE0001F710 /* AppDelegate.swift */,
|
C6F99C3A204DE6BE0001F710 /* AppDelegate.swift */,
|
||||||
C6F99C3C204DE6BE0001F710 /* ViewController.swift */,
|
C6F99C3C204DE6BE0001F710 /* ViewController.swift */,
|
||||||
C6A3424B204DF98E00E062DD /* JitsiViewController.swift */,
|
|
||||||
C6F99C3E204DE6BE0001F710 /* Main.storyboard */,
|
C6F99C3E204DE6BE0001F710 /* Main.storyboard */,
|
||||||
C6F99C41204DE6BE0001F710 /* Assets.xcassets */,
|
C6F99C41204DE6BE0001F710 /* Assets.xcassets */,
|
||||||
C6F99C43204DE6BE0001F710 /* LaunchScreen.storyboard */,
|
C6F99C43204DE6BE0001F710 /* LaunchScreen.storyboard */,
|
||||||
|
@ -103,12 +104,13 @@
|
||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = C6F99C49204DE6BE0001F710 /* Build configuration list for PBXNativeTarget "PiPApp" */;
|
buildConfigurationList = C6F99C49204DE6BE0001F710 /* Build configuration list for PBXNativeTarget "PiPApp" */;
|
||||||
buildPhases = (
|
buildPhases = (
|
||||||
|
C6A3424A204DF91D00E062DD /* Run Adjust ATS for loading JS bundle */,
|
||||||
|
C6F99C62204DEFFE0001F710 /* Run React Packager */,
|
||||||
C6F99C33204DE6BE0001F710 /* Sources */,
|
C6F99C33204DE6BE0001F710 /* Sources */,
|
||||||
C6F99C34204DE6BE0001F710 /* Frameworks */,
|
C6F99C34204DE6BE0001F710 /* Frameworks */,
|
||||||
C6F99C61204DEDC20001F710 /* Embed Frameworks */,
|
|
||||||
C6F99C35204DE6BE0001F710 /* Resources */,
|
C6F99C35204DE6BE0001F710 /* Resources */,
|
||||||
C6F99C62204DEFFE0001F710 /* Run React Packager */,
|
C6F99C61204DEDC20001F710 /* Embed Frameworks */,
|
||||||
C6A3424A204DF91D00E062DD /* Run Adjust ATS for loading JS bundle */,
|
C6A3426E20503ECC00E062DD /* Adjust embedded framework architectures */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
|
@ -132,6 +134,11 @@
|
||||||
C6F99C36204DE6BE0001F710 = {
|
C6F99C36204DE6BE0001F710 = {
|
||||||
CreatedOnToolsVersion = 9.2;
|
CreatedOnToolsVersion = 9.2;
|
||||||
ProvisioningStyle = Automatic;
|
ProvisioningStyle = Automatic;
|
||||||
|
SystemCapabilities = {
|
||||||
|
com.apple.BackgroundModes = {
|
||||||
|
enabled = 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -181,6 +188,20 @@
|
||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "../scripts/fixup-ats.sh";
|
shellScript = "../scripts/fixup-ats.sh";
|
||||||
};
|
};
|
||||||
|
C6A3426E20503ECC00E062DD /* Adjust embedded framework architectures */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
);
|
||||||
|
name = "Adjust embedded framework architectures";
|
||||||
|
outputPaths = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "../scripts/fixup-frameworks.sh";
|
||||||
|
};
|
||||||
C6F99C62204DEFFE0001F710 /* Run React Packager */ = {
|
C6F99C62204DEFFE0001F710 /* Run React Packager */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
@ -204,7 +225,6 @@
|
||||||
files = (
|
files = (
|
||||||
C6F99C3D204DE6BE0001F710 /* ViewController.swift in Sources */,
|
C6F99C3D204DE6BE0001F710 /* ViewController.swift in Sources */,
|
||||||
C6F99C3B204DE6BE0001F710 /* AppDelegate.swift in Sources */,
|
C6F99C3B204DE6BE0001F710 /* AppDelegate.swift in Sources */,
|
||||||
C6A3424C204DF98E00E062DD /* JitsiViewController.swift in Sources */,
|
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
@ -342,7 +362,9 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
FRAMEWORK_SEARCH_PATHS = "../../node_modules/react-native-webrtc/ios";
|
||||||
INFOPLIST_FILE = src/Info.plist;
|
INFOPLIST_FILE = src/Info.plist;
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 10.3;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.jitsi.PiPApp;
|
PRODUCT_BUNDLE_IDENTIFIER = com.jitsi.PiPApp;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
@ -356,7 +378,9 @@
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
FRAMEWORK_SEARCH_PATHS = "../../node_modules/react-native-webrtc/ios";
|
||||||
INFOPLIST_FILE = src/Info.plist;
|
INFOPLIST_FILE = src/Info.plist;
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 10.3;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.jitsi.PiPApp;
|
PRODUCT_BUNDLE_IDENTIFIER = com.jitsi.PiPApp;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
</connections>
|
</connections>
|
||||||
</button>
|
</button>
|
||||||
</subviews>
|
</subviews>
|
||||||
|
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstItem="QxY-C8-fwD" firstAttribute="centerX" secondItem="6Tk-OE-BBY" secondAttribute="centerX" id="6a6-l1-7Ct"/>
|
<constraint firstItem="QxY-C8-fwD" firstAttribute="centerX" secondItem="6Tk-OE-BBY" secondAttribute="centerX" id="6a6-l1-7Ct"/>
|
||||||
<constraint firstItem="QxY-C8-fwD" firstAttribute="centerY" secondItem="6Tk-OE-BBY" secondAttribute="centerY" id="Hfg-TH-0g2"/>
|
<constraint firstItem="QxY-C8-fwD" firstAttribute="centerY" secondItem="6Tk-OE-BBY" secondAttribute="centerY" id="Hfg-TH-0g2"/>
|
||||||
|
@ -41,20 +42,5 @@
|
||||||
</objects>
|
</objects>
|
||||||
<point key="canvasLocation" x="32.799999999999997" y="658.92053973013503"/>
|
<point key="canvasLocation" x="32.799999999999997" y="658.92053973013503"/>
|
||||||
</scene>
|
</scene>
|
||||||
<!--JitsiViewController-->
|
|
||||||
<scene sceneID="V5C-nQ-uqb">
|
|
||||||
<objects>
|
|
||||||
<viewController id="B84-hY-B21" userLabel="JitsiViewController" customClass="JitsiViewController" customModule="PiPApp" customModuleProvider="target" sceneMemberID="viewController">
|
|
||||||
<view key="view" contentMode="scaleToFill" id="nMf-dX-t08" customClass="JitsiMeetView">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
|
||||||
<viewLayoutGuide key="safeArea" id="W4q-U5-6O5"/>
|
|
||||||
</view>
|
|
||||||
</viewController>
|
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="Zdh-Kt-gVo" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
|
||||||
</objects>
|
|
||||||
<point key="canvasLocation" x="1023" y="643"/>
|
|
||||||
</scene>
|
|
||||||
</scenes>
|
</scenes>
|
||||||
</document>
|
</document>
|
||||||
|
|
|
@ -20,6 +20,10 @@
|
||||||
<string>1</string>
|
<string>1</string>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>UIBackgroundModes</key>
|
||||||
|
<array>
|
||||||
|
<string>audio</string>
|
||||||
|
</array>
|
||||||
<key>UILaunchStoryboardName</key>
|
<key>UILaunchStoryboardName</key>
|
||||||
<string>LaunchScreen</string>
|
<string>LaunchScreen</string>
|
||||||
<key>UIMainStoryboardFile</key>
|
<key>UIMainStoryboardFile</key>
|
||||||
|
@ -34,6 +38,19 @@
|
||||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||||
</array>
|
</array>
|
||||||
|
<key>NSAppTransportSecurity</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSExceptionDomains</key>
|
||||||
|
<dict>
|
||||||
|
<key>localhost</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<key>NSAllowsArbitraryLoads</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||||
<array>
|
<array>
|
||||||
<string>UIInterfaceOrientationPortrait</string>
|
<string>UIInterfaceOrientationPortrait</string>
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
//
|
|
||||||
// JitsiViewController.swift
|
|
||||||
// PiPApp
|
|
||||||
//
|
|
||||||
// Created by Daniel Ornelas on 3/5/18.
|
|
||||||
// Copyright © 2018 Atlassian Inc. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import JitsiMeet
|
|
||||||
import UIKit
|
|
||||||
|
|
||||||
final class JitsiViewController: UIViewController {
|
|
||||||
|
|
||||||
override func viewDidLoad() {
|
|
||||||
super.viewDidLoad()
|
|
||||||
|
|
||||||
guard let jitsiView = self.view as? JitsiMeetView else { return }
|
|
||||||
|
|
||||||
jitsiView.welcomePageEnabled = true
|
|
||||||
jitsiView.load(nil)
|
|
||||||
|
|
||||||
// TODO: delete me, this is only testing access to swift object in SDK
|
|
||||||
let jitsiManager = JitsiManager()
|
|
||||||
jitsiManager.testMe()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -13,6 +13,8 @@ class ViewController: UIViewController {
|
||||||
|
|
||||||
@IBOutlet weak var videoButton: UIButton?
|
@IBOutlet weak var videoButton: UIButton?
|
||||||
|
|
||||||
|
private var jitsiMeetManager: JitsiMeetManager?
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
}
|
}
|
||||||
|
@ -20,7 +22,10 @@ class ViewController: UIViewController {
|
||||||
// MARK: - Actions
|
// MARK: - Actions
|
||||||
|
|
||||||
@IBAction func startMeeting(sender: Any?) {
|
@IBAction func startMeeting(sender: Any?) {
|
||||||
print("test")
|
//let url = URL(string: "")
|
||||||
|
self.jitsiMeetManager = JitsiMeetManager()
|
||||||
|
jitsiMeetManager?.welcomeScreenEnabled = true
|
||||||
|
jitsiMeetManager?.load(withUrl: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,10 @@
|
||||||
0BCA496C1EC4BBF900B793EE /* jitsi.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0BCA496B1EC4BBF900B793EE /* jitsi.ttf */; };
|
0BCA496C1EC4BBF900B793EE /* jitsi.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 0BCA496B1EC4BBF900B793EE /* jitsi.ttf */; };
|
||||||
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, ); }; };
|
||||||
0F65EECE1D95DA94561BB47E /* libPods-JitsiMeet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 03F2ADC957FF109849B7FCA1 /* libPods-JitsiMeet.a */; };
|
0F65EECE1D95DA94561BB47E /* libPods-JitsiMeet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 03F2ADC957FF109849B7FCA1 /* libPods-JitsiMeet.a */; };
|
||||||
C6F99C14204DB63E0001F710 /* JitsiManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6F99C12204DB63D0001F710 /* JitsiManager.swift */; };
|
C6A3425F204EF76800E062DD /* JitsiMeetWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6A3425C204EF76800E062DD /* JitsiMeetWindow.swift */; };
|
||||||
|
C6A34260204EF76800E062DD /* JitsiMeetManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6A3425D204EF76800E062DD /* JitsiMeetManager.swift */; };
|
||||||
|
C6A34261204EF76800E062DD /* DragGestureController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6A3425E204EF76800E062DD /* DragGestureController.swift */; };
|
||||||
|
C6A3426D204F1C3300E062DD /* JitsiMeetViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6A3426C204F1C3300E062DD /* JitsiMeetViewController.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 */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
|
@ -57,7 +60,10 @@
|
||||||
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>"; };
|
||||||
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>"; };
|
||||||
C6F99C12204DB63D0001F710 /* JitsiManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JitsiManager.swift; sourceTree = "<group>"; };
|
C6A3425C204EF76800E062DD /* JitsiMeetWindow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JitsiMeetWindow.swift; sourceTree = "<group>"; };
|
||||||
|
C6A3425D204EF76800E062DD /* JitsiMeetManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JitsiMeetManager.swift; sourceTree = "<group>"; };
|
||||||
|
C6A3425E204EF76800E062DD /* DragGestureController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DragGestureController.swift; sourceTree = "<group>"; };
|
||||||
|
C6A3426C204F1C3300E062DD /* JitsiMeetViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JitsiMeetViewController.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>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
|
@ -107,13 +113,13 @@
|
||||||
0BD906E71EC0C00300C8C18E /* src */ = {
|
0BD906E71EC0C00300C8C18E /* src */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
C6A3426B204F127900E062DD /* JitsiMeetManager */,
|
||||||
0BCA495C1EC4B6C600B793EE /* AudioMode.m */,
|
0BCA495C1EC4B6C600B793EE /* AudioMode.m */,
|
||||||
0BB9AD7C1F60356D001C08DB /* AppInfo.m */,
|
0BB9AD7C1F60356D001C08DB /* AppInfo.m */,
|
||||||
0BB9AD7A1F5EC8F4001C08DB /* CallKit.m */,
|
0BB9AD7A1F5EC8F4001C08DB /* CallKit.m */,
|
||||||
0BA13D301EE83FF8007BEF7F /* ExternalAPI.m */,
|
0BA13D301EE83FF8007BEF7F /* ExternalAPI.m */,
|
||||||
0BD906E91EC0C00300C8C18E /* Info.plist */,
|
0BD906E91EC0C00300C8C18E /* Info.plist */,
|
||||||
0B7C2CFC200F51D60060D076 /* LaunchOptions.m */,
|
0B7C2CFC200F51D60060D076 /* LaunchOptions.m */,
|
||||||
C6F99C12204DB63D0001F710 /* JitsiManager.swift */,
|
|
||||||
0BD906E81EC0C00300C8C18E /* JitsiMeet.h */,
|
0BD906E81EC0C00300C8C18E /* JitsiMeet.h */,
|
||||||
0B412F161EDEC65D00B1A0A6 /* JitsiMeetView.h */,
|
0B412F161EDEC65D00B1A0A6 /* JitsiMeetView.h */,
|
||||||
0B412F171EDEC65D00B1A0A6 /* JitsiMeetView.m */,
|
0B412F171EDEC65D00B1A0A6 /* JitsiMeetView.m */,
|
||||||
|
@ -149,6 +155,17 @@
|
||||||
name = Pods;
|
name = Pods;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
C6A3426B204F127900E062DD /* JitsiMeetManager */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
C6A3425C204EF76800E062DD /* JitsiMeetWindow.swift */,
|
||||||
|
C6A3425D204EF76800E062DD /* JitsiMeetManager.swift */,
|
||||||
|
C6A3426C204F1C3300E062DD /* JitsiMeetViewController.swift */,
|
||||||
|
C6A3425E204EF76800E062DD /* DragGestureController.swift */,
|
||||||
|
);
|
||||||
|
path = JitsiMeetManager;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
/* End PBXGroup section */
|
/* End PBXGroup section */
|
||||||
|
|
||||||
/* Begin PBXHeadersBuildPhase section */
|
/* Begin PBXHeadersBuildPhase section */
|
||||||
|
@ -312,15 +329,18 @@
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
0BB9AD7B1F5EC8F4001C08DB /* CallKit.m in Sources */,
|
0BB9AD7B1F5EC8F4001C08DB /* CallKit.m in Sources */,
|
||||||
|
C6A34260204EF76800E062DD /* JitsiMeetManager.swift in Sources */,
|
||||||
0BB9AD7D1F60356D001C08DB /* AppInfo.m in Sources */,
|
0BB9AD7D1F60356D001C08DB /* AppInfo.m in Sources */,
|
||||||
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 */,
|
0B7C2CFD200F51D60060D076 /* LaunchOptions.m in Sources */,
|
||||||
C6F99C14204DB63E0001F710 /* JitsiManager.swift in Sources */,
|
C6A3426D204F1C3300E062DD /* JitsiMeetViewController.swift in Sources */,
|
||||||
|
C6A3425F204EF76800E062DD /* JitsiMeetWindow.swift in Sources */,
|
||||||
0BCA495F1EC4B6C600B793EE /* AudioMode.m in Sources */,
|
0BCA495F1EC4B6C600B793EE /* AudioMode.m in Sources */,
|
||||||
0B44A0191F902126009D1D64 /* MPVolumeViewManager.m in Sources */,
|
0B44A0191F902126009D1D64 /* MPVolumeViewManager.m in Sources */,
|
||||||
0BCA49611EC4B6C600B793EE /* Proximity.m in Sources */,
|
0BCA49611EC4B6C600B793EE /* Proximity.m in Sources */,
|
||||||
|
C6A34261204EF76800E062DD /* DragGestureController.swift in Sources */,
|
||||||
0B412F191EDEC65D00B1A0A6 /* JitsiMeetView.m in Sources */,
|
0B412F191EDEC65D00B1A0A6 /* JitsiMeetView.m in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
//
|
|
||||||
// JitsiManager.swift
|
|
||||||
// JitsiMeet
|
|
||||||
//
|
|
||||||
// Created by Daniel Ornelas on 3/5/18.
|
|
||||||
// Copyright © 2018 Jitsi. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
@objc(JitsiManager)
|
|
||||||
public class JitsiManager: NSObject {
|
|
||||||
|
|
||||||
public func testMe() {
|
|
||||||
print("hi there")
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,104 @@
|
||||||
|
// Copyright © 2018 Jitsi. All rights reserved.
|
||||||
|
|
||||||
|
final class DragGestureController {
|
||||||
|
|
||||||
|
var insets: UIEdgeInsets = UIEdgeInsets.zero
|
||||||
|
|
||||||
|
private var frameBeforeDragging: CGRect = CGRect.zero
|
||||||
|
private weak var view: UIView?
|
||||||
|
private lazy var panGesture: UIPanGestureRecognizer = {
|
||||||
|
return UIPanGestureRecognizer(target: self, action: #selector(handlePan(gesture:)))
|
||||||
|
}()
|
||||||
|
|
||||||
|
func startDragListener(inView view: UIView) {
|
||||||
|
self.view = view
|
||||||
|
view.addGestureRecognizer(panGesture)
|
||||||
|
panGesture.isEnabled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func stopDragListener() {
|
||||||
|
panGesture.isEnabled = false
|
||||||
|
view?.removeGestureRecognizer(panGesture)
|
||||||
|
view = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc private func handlePan(gesture: UIPanGestureRecognizer) {
|
||||||
|
guard let view = self.view else { return }
|
||||||
|
|
||||||
|
let translation = gesture.translation(in: view.superview)
|
||||||
|
let velocity = gesture.velocity(in: view.superview)
|
||||||
|
var frame = frameBeforeDragging
|
||||||
|
|
||||||
|
switch gesture.state {
|
||||||
|
case .began:
|
||||||
|
frameBeforeDragging = view.frame
|
||||||
|
|
||||||
|
case .changed:
|
||||||
|
frame.origin.x = floor(frame.origin.x + translation.x)
|
||||||
|
frame.origin.y = floor(frame.origin.y + translation.y)
|
||||||
|
view.frame = frame
|
||||||
|
|
||||||
|
case .ended:
|
||||||
|
let currentPos = view.frame.origin
|
||||||
|
let finalPos = calculateFinalPosition()
|
||||||
|
|
||||||
|
let distance = CGPoint(x: currentPos.x - finalPos.x,
|
||||||
|
y: currentPos.y - finalPos.y)
|
||||||
|
let distanceMagnitude = magnitude(vector: distance)
|
||||||
|
let velocityMagnitude = magnitude(vector: velocity)
|
||||||
|
let animationDuration = 0.5
|
||||||
|
let initialSpringVelocity = velocityMagnitude / distanceMagnitude / CGFloat(animationDuration)
|
||||||
|
|
||||||
|
frame.origin = CGPoint(x: finalPos.x, y: finalPos.y)
|
||||||
|
|
||||||
|
UIView.animate(withDuration: animationDuration,
|
||||||
|
delay: 0,
|
||||||
|
usingSpringWithDamping: 0.9,
|
||||||
|
initialSpringVelocity: initialSpringVelocity,
|
||||||
|
options: .curveLinear,
|
||||||
|
animations: {
|
||||||
|
view.frame = frame
|
||||||
|
}, completion: nil)
|
||||||
|
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func calculateFinalPosition() -> CGPoint {
|
||||||
|
guard
|
||||||
|
let view = self.view,
|
||||||
|
let bounds = view.superview?.frame
|
||||||
|
else { return CGPoint.zero }
|
||||||
|
|
||||||
|
let currentSize = view.frame.size
|
||||||
|
let adjustedBounds = UIEdgeInsetsInsetRect(bounds, insets)
|
||||||
|
let threshold: CGFloat = 20.0
|
||||||
|
let velocity = panGesture.velocity(in: view.superview)
|
||||||
|
let location = panGesture.location(in: view.superview)
|
||||||
|
|
||||||
|
let goLeft: Bool
|
||||||
|
if fabs(velocity.x) > threshold {
|
||||||
|
goLeft = velocity.x < -threshold
|
||||||
|
} else {
|
||||||
|
goLeft = location.x < bounds.midX
|
||||||
|
}
|
||||||
|
|
||||||
|
let goUp: Bool
|
||||||
|
if fabs(velocity.y) > threshold {
|
||||||
|
goUp = velocity.y < -threshold
|
||||||
|
} else {
|
||||||
|
goUp = location.y < bounds.midY
|
||||||
|
}
|
||||||
|
|
||||||
|
let finalPosX: CGFloat = goLeft ? adjustedBounds.origin.x : bounds.size.width - insets.right - currentSize.width
|
||||||
|
let finalPosY: CGFloat = goUp ? adjustedBounds.origin.y : bounds.size.height - insets.bottom - currentSize.height
|
||||||
|
|
||||||
|
return CGPoint(x: finalPosX, y: finalPosY)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func magnitude(vector: CGPoint) -> CGFloat {
|
||||||
|
return sqrt(pow(vector.x, 2) + pow(vector.y, 2))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,146 @@
|
||||||
|
// Copyright © 2018 Jitsi. All rights reserved.
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
/// Creates and present a JitsiMeetView inside of an external window that can be dragged
|
||||||
|
/// when minimized (if PiP mode is enabled)
|
||||||
|
open class JitsiMeetManager: NSObject {
|
||||||
|
|
||||||
|
/// The Jitsi meet view delegate
|
||||||
|
public weak var delegate: JitsiMeetViewDelegate? = nil
|
||||||
|
/// Limits the boundries of meet view position on screen when minimized
|
||||||
|
public var dragBoundInsets: UIEdgeInsets = UIEdgeInsets(top: 25, left: 5, bottom: 5, right: 5)
|
||||||
|
/// Enables PiP mode for this jitsiMeet
|
||||||
|
public var allowPiP: Bool = true
|
||||||
|
/// The size ratio for jitsiMeetView when in PiP mode
|
||||||
|
public var pipSizeRatio: CGFloat = 0.333
|
||||||
|
/// Defines if welcome screen should be on
|
||||||
|
public var welcomeScreenEnabled: Bool = false
|
||||||
|
|
||||||
|
fileprivate let dragController: DragGestureController = DragGestureController()
|
||||||
|
|
||||||
|
fileprivate lazy var meetViewController: JitsiMeetViewController = { return self.makeMeetViewController() }()
|
||||||
|
fileprivate lazy var meetWindow: JitsiMeetWindow = { return self.makeMeetWindow() }()
|
||||||
|
fileprivate var meetingInPiP: Bool = false
|
||||||
|
|
||||||
|
/// Presents and loads a jitsi meet view
|
||||||
|
///
|
||||||
|
/// - Parameter url: The url of the presentation
|
||||||
|
public func load(withUrl url: URL?) {
|
||||||
|
meetWindow.show()
|
||||||
|
meetViewController.jitsiMeetView.load(url)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Presents and loads a jitsi meet view with configuration
|
||||||
|
///
|
||||||
|
/// - Parameter urlObject: A dictionary of keys to be used for configuration
|
||||||
|
public func load(withUrlObject urlObject: [AnyHashable : Any]?) {
|
||||||
|
meetWindow.show()
|
||||||
|
meetViewController.jitsiMeetView.loadURLObject(urlObject)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Manage PiP switching
|
||||||
|
|
||||||
|
// update size animation
|
||||||
|
fileprivate func updateMeetViewSize(isPiP: Bool) {
|
||||||
|
UIView.animate(withDuration: 0.25) {
|
||||||
|
self.meetViewController.view.frame = self.meetViewRect(isPiP: isPiP)
|
||||||
|
self.meetViewController.view.setNeedsLayout()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func meetViewRect(isPiP: Bool) -> CGRect {
|
||||||
|
guard isPiP else {
|
||||||
|
return meetWindow.bounds
|
||||||
|
}
|
||||||
|
let bounds = meetWindow.bounds
|
||||||
|
|
||||||
|
// resize to suggested ratio and position to the bottom right
|
||||||
|
let adjustedBounds = UIEdgeInsetsInsetRect(bounds, dragBoundInsets)
|
||||||
|
let size = CGSize(width: bounds.size.width * pipSizeRatio,
|
||||||
|
height: bounds.size.height * pipSizeRatio)
|
||||||
|
let x: CGFloat = adjustedBounds.maxX - size.width
|
||||||
|
let y: CGFloat = adjustedBounds.maxY - size.height
|
||||||
|
return CGRect(x: x, y: y, width: size.width, height: size.height)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - helpers
|
||||||
|
|
||||||
|
fileprivate func cleanUp() {
|
||||||
|
// TODO: more clean up work on this
|
||||||
|
|
||||||
|
dragController.stopDragListener()
|
||||||
|
meetWindow.isHidden = true
|
||||||
|
}
|
||||||
|
|
||||||
|
private func makeMeetViewController() -> JitsiMeetViewController {
|
||||||
|
let vc = JitsiMeetViewController()
|
||||||
|
vc.jitsiMeetView.delegate = self
|
||||||
|
vc.jitsiMeetView.welcomePageEnabled = self.welcomeScreenEnabled
|
||||||
|
vc.jitsiMeetView.pictureInPictureEnabled = self.allowPiP
|
||||||
|
return vc
|
||||||
|
}
|
||||||
|
|
||||||
|
private func makeMeetWindow() -> JitsiMeetWindow {
|
||||||
|
let window = JitsiMeetWindow(frame: UIScreen.main.bounds)
|
||||||
|
window.backgroundColor = .clear
|
||||||
|
window.windowLevel = UIWindowLevelStatusBar + 100
|
||||||
|
window.rootViewController = self.meetViewController
|
||||||
|
return window
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension JitsiMeetManager: JitsiMeetViewDelegate {
|
||||||
|
|
||||||
|
public func conferenceWillJoin(_ data: [AnyHashable : Any]!) {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.delegate?.conferenceWillJoin!(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func conferenceJoined(_ data: [AnyHashable : Any]!) {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.delegate?.conferenceJoined!(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func conferenceWillLeave(_ data: [AnyHashable : Any]!) {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.delegate?.conferenceWillLeave!(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func conferenceLeft(_ data: [AnyHashable : Any]!) {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.cleanUp()
|
||||||
|
|
||||||
|
self.delegate?.conferenceLeft!(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func conferenceFailed(_ data: [AnyHashable : Any]!) {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.cleanUp()
|
||||||
|
|
||||||
|
self.delegate?.conferenceFailed!(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func loadConfigError(_ data: [AnyHashable : Any]!) {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.delegate?.loadConfigError!(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func enterPicture(inPicture data: [AnyHashable : Any]!) {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.dragController.startDragListener(inView: self.meetViewController.view)
|
||||||
|
self.dragController.insets = self.dragBoundInsets
|
||||||
|
|
||||||
|
self.meetingInPiP = true
|
||||||
|
self.updateMeetViewSize(isPiP: true)
|
||||||
|
|
||||||
|
self.delegate?.enterPicture!(inPicture: data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
// Copyright © 2018 Jitsi. All rights reserved.
|
||||||
|
|
||||||
|
|
||||||
|
/// Wrapper ViewController of a JitsiMeetView
|
||||||
|
///
|
||||||
|
/// TODO: should consider refactor and move out several logic of the JitsiMeetView to
|
||||||
|
/// this class
|
||||||
|
open class JitsiMeetViewController: UIViewController {
|
||||||
|
|
||||||
|
private(set) var jitsiMeetView: JitsiMeetView = JitsiMeetView()
|
||||||
|
|
||||||
|
override open func loadView() {
|
||||||
|
super.loadView()
|
||||||
|
self.view = jitsiMeetView
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
// Copyright © 2018 Jitsi. All rights reserved.
|
||||||
|
|
||||||
|
open class JitsiMeetWindow: UIWindow {
|
||||||
|
|
||||||
|
/// Help out to bubble up the gesture detection outside of the rootVC frame
|
||||||
|
open override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
|
||||||
|
guard let vc = rootViewController else {
|
||||||
|
return super.point(inside: point, with: event)
|
||||||
|
}
|
||||||
|
return vc.view.frame.contains(point)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// animate in the window
|
||||||
|
open func show() {
|
||||||
|
if self.isHidden || self.alpha < 1 {
|
||||||
|
self.isHidden = false
|
||||||
|
self.alpha = 0
|
||||||
|
|
||||||
|
UIView.animate(
|
||||||
|
withDuration: 0.1,
|
||||||
|
delay: 0,
|
||||||
|
options: .beginFromCurrentState,
|
||||||
|
animations: {
|
||||||
|
self.alpha = 1
|
||||||
|
},
|
||||||
|
completion: nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// animate out the window
|
||||||
|
open func hide() {
|
||||||
|
if !self.isHidden || self.alpha > 0 {
|
||||||
|
UIView.animate(
|
||||||
|
withDuration: 0.1,
|
||||||
|
delay: 0,
|
||||||
|
options: .beginFromCurrentState,
|
||||||
|
animations: {
|
||||||
|
self.alpha = 0
|
||||||
|
self.isHidden = true
|
||||||
|
},
|
||||||
|
completion: nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
import { NativeModules } from 'react-native';
|
import { NativeModules } from 'react-native';
|
||||||
|
|
||||||
|
import { Platform } from '../../base/react';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ENTER_PICTURE_IN_PICTURE,
|
ENTER_PICTURE_IN_PICTURE,
|
||||||
_SET_EMITTER_SUBSCRIPTIONS
|
_SET_EMITTER_SUBSCRIPTIONS
|
||||||
|
@ -28,10 +30,12 @@ export function enterPictureInPicture() {
|
||||||
&& (conference || joining)) {
|
&& (conference || joining)) {
|
||||||
const { PictureInPicture } = NativeModules;
|
const { PictureInPicture } = NativeModules;
|
||||||
const p
|
const p
|
||||||
= PictureInPicture
|
= Platform.OS === 'android'
|
||||||
? PictureInPicture.enterPictureInPicture()
|
? PictureInPicture
|
||||||
: Promise.reject(
|
? PictureInPicture.enterPictureInPicture()
|
||||||
new Error('Picture-in-Picture not supported'));
|
: Promise.reject(
|
||||||
|
new Error('Picture-in-Picture not supported'))
|
||||||
|
: Promise.resolve();
|
||||||
|
|
||||||
p.then(
|
p.then(
|
||||||
() => dispatch({ type: ENTER_PICTURE_IN_PICTURE }),
|
() => dispatch({ type: ENTER_PICTURE_IN_PICTURE }),
|
||||||
|
|
Loading…
Reference in New Issue