201 lines
6.9 KiB
Swift
201 lines
6.9 KiB
Swift
//
|
|
// WindowManger.swift
|
|
// TUICallKit
|
|
//
|
|
// Created by vincepzhang on 2023/2/22.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
class WindowManager: NSObject, FloatingWindowViewDelegate {
|
|
|
|
static let instance = WindowManager()
|
|
|
|
var isFloating = false
|
|
var floatWindowBeganPoint: CGPoint = .zero
|
|
|
|
let mediaTypeObserver = Observer()
|
|
|
|
let callWindow: UIWindow = {
|
|
let callWindow = UIWindow()
|
|
callWindow.windowLevel = .alert - 1
|
|
return callWindow
|
|
}()
|
|
|
|
let floatWindow: UIWindow = {
|
|
let floatWindow = UIWindow()
|
|
floatWindow.windowLevel = .alert - 1
|
|
floatWindow.layer.masksToBounds = true
|
|
return floatWindow
|
|
}()
|
|
|
|
var callKitViewController: CallKitViewController?
|
|
|
|
func getCallKitViewController() -> CallKitViewController {
|
|
if let callKitViewController = callKitViewController {
|
|
return callKitViewController
|
|
} else {
|
|
let newCallKitViewController = CallKitViewController()
|
|
callKitViewController = newCallKitViewController
|
|
return newCallKitViewController
|
|
}
|
|
}
|
|
|
|
override init() {
|
|
super.init()
|
|
registerObserveState()
|
|
}
|
|
|
|
deinit {
|
|
TUICallState.instance.mediaType.removeObserver(mediaTypeObserver)
|
|
}
|
|
|
|
func showCallWindow(_ isIncomingCall: Bool = true) {
|
|
if isIncomingCall && TUICallState.instance.selfUser.value.callRole.value == .called {
|
|
showIncomingFloatView()
|
|
} else {
|
|
showCallView()
|
|
}
|
|
}
|
|
|
|
func closeCallWindow() {
|
|
callKitViewController = nil
|
|
callWindow.rootViewController = nil
|
|
callWindow.isHidden = true
|
|
}
|
|
|
|
func showIncomingFloatView() {
|
|
let viewController = UIViewController()
|
|
viewController.view.addSubview(IncomingFloatView(frame: CGRect.zero))
|
|
callWindow.rootViewController = viewController
|
|
callWindow.isHidden = false
|
|
callWindow.backgroundColor = UIColor.clear
|
|
callWindow.frame = CGRect(x: 8.scaleWidth(),
|
|
y: StatusBar_Height + 10,
|
|
width: Screen_Width - 16.scaleWidth(),
|
|
height: 92.scaleWidth())
|
|
callWindow.t_makeKeyAndVisible()
|
|
}
|
|
|
|
func showCallView() {
|
|
closeFloatWindow()
|
|
callWindow.rootViewController = CallKitNavigationController(rootViewController: getCallKitViewController())
|
|
callWindow.isHidden = false
|
|
callWindow.frame = CGRect(x: 0, y: 0, width: Screen_Width, height: Screen_Height)
|
|
callWindow.t_makeKeyAndVisible()
|
|
}
|
|
|
|
func showFloatWindow() {
|
|
closeCallWindow()
|
|
let floatViewController = FloatWindowViewController()
|
|
floatViewController.delegate = self
|
|
floatWindow.rootViewController = floatViewController
|
|
floatWindow.backgroundColor = UIColor.clear
|
|
floatWindow.isHidden = false
|
|
floatWindow.frame = getFloatWindowFrame()
|
|
updateFloatWindowFrame()
|
|
floatWindow.t_makeKeyAndVisible()
|
|
isFloating = true
|
|
}
|
|
|
|
func closeFloatWindow() {
|
|
floatWindow.rootViewController = nil
|
|
floatWindow.isHidden = true
|
|
isFloating = false
|
|
}
|
|
|
|
func getFloatWindowFrame() -> CGRect {
|
|
if TUICallState.instance.scene.value == .group {
|
|
return kMicroGroupViewRect
|
|
}
|
|
|
|
if TUICallState.instance.mediaType.value == .audio {
|
|
return kMicroAudioViewRect
|
|
} else {
|
|
return kMicroVideoViewRect
|
|
}
|
|
}
|
|
|
|
func updateFloatWindowFrame() {
|
|
let originY = floatWindow.frame.origin.y
|
|
|
|
if TUICallState.instance.scene.value == .group {
|
|
let dstX = floatWindow.frame.origin.x < (Screen_Width / 2.0) ? 0 : (Screen_Width - kMicroGroupViewWidth)
|
|
floatWindow.frame = CGRect(x: dstX, y: originY, width: kMicroGroupViewWidth, height: kMicroGroupViewHeight)
|
|
return
|
|
}
|
|
|
|
if TUICallState.instance.mediaType.value == .audio {
|
|
let dstX = floatWindow.frame.origin.x < (Screen_Width / 2.0) ? 0 : (Screen_Width - kMicroAudioViewWidth)
|
|
floatWindow.frame = CGRect(x: dstX, y: originY, width: kMicroAudioViewWidth, height: kMicroAudioViewHeight)
|
|
} else {
|
|
let dstX = floatWindow.frame.origin.x < (Screen_Width / 2.0) ? 0 : (Screen_Width - kMicroVideoViewWidth)
|
|
floatWindow.frame = CGRect(x: dstX, y: originY, width: kMicroVideoViewWidth, height: kMicroVideoViewHeight)
|
|
}
|
|
}
|
|
|
|
func registerObserveState() {
|
|
TUICallState.instance.mediaType.addObserver(mediaTypeObserver, closure: { [weak self] newValue, _ in
|
|
guard let self = self else { return }
|
|
if self.isFloating {
|
|
self.updateFloatWindowFrame()
|
|
}
|
|
})
|
|
}
|
|
|
|
// MARK: FloatingWindowViewDelegate
|
|
func tapGestureAction(tapGesture: UITapGestureRecognizer) {
|
|
showCallWindow(false)
|
|
}
|
|
|
|
func panGestureAction(panGesture: UIPanGestureRecognizer) {
|
|
switch panGesture.state {
|
|
case .began:
|
|
floatWindowBeganPoint = floatWindow.frame.origin
|
|
break
|
|
case.changed:
|
|
let point = panGesture.translation(in: floatWindow)
|
|
var dstX = floatWindowBeganPoint.x + point.x
|
|
var dstY = floatWindowBeganPoint.y + point.y
|
|
|
|
if dstX < 0 {
|
|
dstX = 0
|
|
} else if dstX > (Screen_Width - floatWindow.frame.size.width) {
|
|
dstX = Screen_Width - floatWindow.frame.size.width
|
|
}
|
|
|
|
if dstY < 0 {
|
|
dstY = 0
|
|
} else if dstY > (Screen_Height - floatWindow.frame.size.height) {
|
|
dstY = Screen_Height - floatWindow.frame.size.height
|
|
|
|
}
|
|
|
|
floatWindow.frame = CGRect(x: dstX,
|
|
y: dstY,
|
|
width: floatWindow.frame.size.width,
|
|
height: floatWindow.frame.size.height)
|
|
break
|
|
case.cancelled:
|
|
break
|
|
case.ended:
|
|
var dstX: CGFloat = 0
|
|
let currentCenterX: CGFloat = floatWindow.frame.origin.x + floatWindow.frame.size.width / 2.0
|
|
|
|
if currentCenterX < Screen_Width / 2 {
|
|
dstX = CGFloat(0)
|
|
} else if currentCenterX > Screen_Width / 2 {
|
|
dstX = CGFloat(Screen_Width - floatWindow.frame.size.width)
|
|
}
|
|
|
|
floatWindow.frame = CGRect(x: dstX,
|
|
y: floatWindow.frame.origin.y,
|
|
width: floatWindow.frame.size.width,
|
|
height: floatWindow.frame.size.height)
|
|
break
|
|
default:
|
|
break
|
|
}
|
|
}
|
|
}
|