diff --git a/ios/sdk/image-resize@2x.png b/ios/sdk/image-resize@2x.png new file mode 100644 index 000000000..d66dd8a3f Binary files /dev/null and b/ios/sdk/image-resize@2x.png differ diff --git a/ios/sdk/image-resize@3x.png b/ios/sdk/image-resize@3x.png new file mode 100644 index 000000000..7a4244fec Binary files /dev/null and b/ios/sdk/image-resize@3x.png differ diff --git a/ios/sdk/sdk.xcodeproj/project.pbxproj b/ios/sdk/sdk.xcodeproj/project.pbxproj index 8a7cc1c14..b3759bcd9 100644 --- a/ios/sdk/sdk.xcodeproj/project.pbxproj +++ b/ios/sdk/sdk.xcodeproj/project.pbxproj @@ -27,6 +27,8 @@ 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, ); }; }; 0F65EECE1D95DA94561BB47E /* libPods-JitsiMeet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 03F2ADC957FF109849B7FCA1 /* libPods-JitsiMeet.a */; }; + C6245F5D2053091D0040BE68 /* image-resize@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = C6245F5B2053091D0040BE68 /* image-resize@2x.png */; }; + C6245F5E2053091D0040BE68 /* image-resize@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = C6245F5C2053091D0040BE68 /* image-resize@3x.png */; }; C6A3425F204EF76800E062DD /* PiPWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6A3425C204EF76800E062DD /* PiPWindow.swift */; }; C6A34260204EF76800E062DD /* JitsiMeetManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6A3425D204EF76800E062DD /* JitsiMeetManager.swift */; }; C6A34261204EF76800E062DD /* DragGestureController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6A3425E204EF76800E062DD /* DragGestureController.swift */; }; @@ -60,6 +62,8 @@ 0BD906E91EC0C00300C8C18E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 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 = ""; }; 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 = ""; }; + C6245F5B2053091D0040BE68 /* image-resize@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "image-resize@2x.png"; sourceTree = ""; }; + C6245F5C2053091D0040BE68 /* image-resize@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "image-resize@3x.png"; sourceTree = ""; }; C6A3425C204EF76800E062DD /* PiPWindow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PiPWindow.swift; sourceTree = ""; }; C6A3425D204EF76800E062DD /* JitsiMeetManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JitsiMeetManager.swift; sourceTree = ""; }; C6A3425E204EF76800E062DD /* DragGestureController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DragGestureController.swift; sourceTree = ""; }; @@ -86,6 +90,8 @@ isa = PBXGroup; children = ( 0BC4B8681F8C01E100CE8B21 /* CallKitIcon.png */, + C6245F5B2053091D0040BE68 /* image-resize@2x.png */, + C6245F5C2053091D0040BE68 /* image-resize@3x.png */, 0BCA496B1EC4BBF900B793EE /* jitsi.ttf */, ); name = Resources; @@ -252,7 +258,9 @@ buildActionMask = 2147483647; files = ( 0BCA496C1EC4BBF900B793EE /* jitsi.ttf in Resources */, + C6245F5D2053091D0040BE68 /* image-resize@2x.png in Resources */, 0BC4B8691F8C03A700CE8B21 /* CallKitIcon.png in Resources */, + C6245F5E2053091D0040BE68 /* image-resize@3x.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -472,7 +480,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = 98E09B5C73D9036B4ED252FC /* Pods-JitsiMeet.debug.xcconfig */; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; @@ -499,7 +507,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = 9C77CA3CC919B081F1A52982 /* Pods-JitsiMeet.release.xcconfig */; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; diff --git a/ios/sdk/src/JitsiMeetManager/PiPWindow/PiPWindow.swift b/ios/sdk/src/JitsiMeetManager/PiPWindow/PiPWindow.swift index 0f65ef394..424859267 100644 --- a/ios/sdk/src/JitsiMeetManager/PiPWindow/PiPWindow.swift +++ b/ios/sdk/src/JitsiMeetManager/PiPWindow/PiPWindow.swift @@ -19,6 +19,10 @@ open class PiPWindow: UIWindow { private let dragController: DragGestureController = DragGestureController() + /// Used when in PiP mode to enable/disable exit PiP UI + private var tapGestureRecognizer: UITapGestureRecognizer? + private var exitPiPButton: UIButton? + /// 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 { @@ -66,6 +70,11 @@ open class PiPWindow: UIWindow { animateRootViewChange() dragController.startDragListener(inView: view) dragController.insets = dragBoundInsets + + // add single tap gesture recognition for displaying exit PiP UI + let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(toggleExitPiP)) + self.tapGestureRecognizer = tapGestureRecognizer + view.addGestureRecognizer(tapGestureRecognizer) } /// Resize the root view to full screen @@ -73,6 +82,14 @@ open class PiPWindow: UIWindow { isInPiP = false animateRootViewChange() dragController.stopDragListener() + + // hide PiP UI + exitPiPButton?.removeFromSuperview() + exitPiPButton = nil + + // remove gesture + tapGestureRecognizer?.removeTarget(self, action: #selector(toggleExitPiP)) + tapGestureRecognizer = nil } /// Stop the dragging gesture of the root view @@ -80,6 +97,22 @@ open class PiPWindow: UIWindow { dragController.stopDragListener() } + /// Customize the presentation of exit pip button + open func configureExitPiPButton(target: Any, action: Selector) -> UIButton { + let buttonImage = UIImage.init(named: "image-resize", in: Bundle(for: type(of: self)), compatibleWith: nil) + let button = UIButton(type: .custom) + let size: CGSize = CGSize(width: 44, height: 44) + button.setImage(buttonImage, for: .normal) + button.backgroundColor = .gray + button.layer.cornerRadius = size.width / 2 + button.frame = CGRect(origin: CGPoint.zero, size: size) + if let view = rootViewController?.view { + button.center = view.convert(view.center, from:view.superview) + } + button.addTarget(target, action: action, for: .touchUpInside) + return button + } + // MARK: - Manage presentation switching private func animateRootViewChange() { @@ -102,4 +135,27 @@ open class PiPWindow: UIWindow { let y: CGFloat = adjustedBounds.maxY - size.height return CGRect(x: x, y: y, width: size.width, height: size.height) } + + // MARK: - Exit PiP + + @objc private func toggleExitPiP() { + guard let view = rootViewController?.view else { return } + + if exitPiPButton == nil { + // show button + let button = configureExitPiPButton(target: self, action: #selector(exitPiP)) + view.addSubview(button) + exitPiPButton = button + + } else { + // hide button + exitPiPButton?.removeFromSuperview() + exitPiPButton = nil + } + + } + + @objc private func exitPiP() { + goToFullScreen() + } }