Files
featherVoice/TUIKit/TUICallKit/TUICallKit-Swift/Service/TUICallKitExtension.swift
2025-08-08 10:49:36 +08:00

308 lines
16 KiB
Swift

//
// TUICallKitExtension.swift
// TUICallKit
//
// Created by vincepzhang on 2023/8/14.
//
import Foundation
import TUICore
import TUICallEngine
class TUICallKitExtension: NSObject, TUIExtensionProtocol {
static let instance = TUICallKitExtension()
var joinGroupCallViewModel = JoinInGroupCallViewModel()
func launchCall(type: TUICallMediaType, groupID: String, pushVC: UINavigationController, isClassic: Bool) {
if !groupID.isEmpty {
var requestParam: [String: Any] = [:]
requestParam[TUICore_TUIContactObjectFactory_SelectGroupMemberVC_GroupID] = groupID
requestParam[TUICore_TUIContactObjectFactory_SelectGroupMemberVC_Name] =
TUIGlobalization.getLocalizedString(forKey: "Make-a-call", bundle: TUIKitLocalizableBundle)
let viewControllerKey = isClassic ? TUICore_TUIContactObjectFactory_SelectGroupMemberVC_Classic :
TUICore_TUIContactObjectFactory_SelectGroupMemberVC_Minimalist
pushVC.push(viewControllerKey, param: requestParam) { [weak self] responseData in
guard let self = self else { return }
guard let modelList = responseData[TUICore_TUIContactObjectFactory_SelectGroupMemberVC_ResultUserList]
as? [AnyObject] else { return }
let userIDs: [String] = modelList.compactMap { $0.userId }
self.startCall(groupID: groupID, userIDs: userIDs, callingType: type)
}
}
}
func startCall(groupID: String, userIDs: [String], callingType: TUICallMediaType) {
let selector = NSSelectorFromString("setOnlineUserOnly")
if TUICallEngine.createInstance().responds(to: selector) {
TUICallEngine.createInstance().perform(selector, with: 0)
}
if groupID.isEmpty {
guard let userID = userIDs.first else { return }
TUICallKit.createInstance().call(userId: userID, callMediaType: callingType)
} else {
TUICallKit.createInstance().groupCall(groupId: groupID, userIdList: userIDs, callMediaType: callingType)
}
}
func doResponseInputViewExtension(param: [String: Any], type: TUICallMediaType, isClassic: Bool) {
let userID = param[TUICore_TUIChatExtension_InputViewMoreItem_UserID] as? String ?? ""
let groupId = param[TUICore_TUIChatExtension_InputViewMoreItem_GroupID] as? String ?? ""
let pushVC = param[TUICore_TUIChatExtension_InputViewMoreItem_PushVC] as? UINavigationController
if !userID.isEmpty {
startCall(groupID: "", userIDs: [userID], callingType: type)
} else if !groupId.isEmpty {
guard let pushVC = pushVC else { return }
launchCall(type: type, groupID: groupId, pushVC: pushVC, isClassic: isClassic)
}
}
// MARK: TUIExtensionProtocol
func onRaiseExtension(_ extensionID: String, parentView: UIView, param: [AnyHashable : Any]?) -> Bool {
if extensionID.isEmpty {
return false
}
guard let groupId = param?[TUICore_TUIChatExtension_ChatViewTopArea_ChatID] as? String,
let isGroup = param?[TUICore_TUIChatExtension_ChatViewTopArea_IsGroup], isGroup as! String == "1" else {
return false
}
if extensionID == TUICore_TUIChatExtension_ChatViewTopArea_ClassicExtensionID ||
extensionID == TUICore_TUIChatExtension_ChatViewTopArea_MinimalistExtensionID {
let joinGroupCallView = JoinInGroupCallView()
joinGroupCallViewModel.setJoinGroupCallView(joinGroupCallView)
joinGroupCallViewModel.getGroupAttributes(groupId)
parentView.subviews.forEach {
if $0 is JoinInGroupCallView {
$0.removeFromSuperview()
}
}
parentView.addSubview(joinGroupCallView)
return true
}
return false
}
func onGetExtension(_ extensionID: String, param: [AnyHashable : Any]?) -> [TUIExtensionInfo]? {
if extensionID.isEmpty {
return nil
}
if extensionID == TUICore_TUIChatExtension_NavigationMoreItem_MinimalistExtensionID {
return getNavigationMoreItemExtensionForMinimalistChat(param: param)
} else if extensionID == TUICore_TUIChatExtension_InputViewMoreItem_ClassicExtensionID {
return getInputViewMoreItemExtensionForClassicChat(param: param)
} else if extensionID == TUICore_TUIContactExtension_FriendProfileActionMenu_ClassicExtensionID {
return getFriendProfileActionMenuExtensionForClassicContact(param: param)
} else if extensionID == TUICore_TUIContactExtension_FriendProfileActionMenu_MinimalistExtensionID {
return getFriendProfileActionMenuExtensionForMinimalistContact(param: param)
} else if extensionID == TUICore_TUIContactExtension_GroupInfoCardActionMenu_MinimalistExtensionID {
return getGroupInfoCardActionMenuExtensionForMinimalistGroup(param: param)
} else {
return nil
}
}
func getNavigationMoreItemExtensionForMinimalistChat(param: [AnyHashable : Any]?) -> [TUIExtensionInfo]? {
guard let param = param else { return nil }
let onClick: ([AnyHashable : Any]?, TUICallMediaType) -> Void = { [weak self] param, type in
guard let self = self else { return }
guard let param = param else { return }
let userID = param[TUICore_TUIChatExtension_NavigationMoreItem_UserID] as? String ?? ""
let groupID = param[TUICore_TUIChatExtension_NavigationMoreItem_GroupID] as? String ?? ""
let pushVC = param[TUICore_TUIChatExtension_NavigationMoreItem_PushVC] as? UINavigationController
if !userID.isEmpty {
self.startCall(groupID: "", userIDs: [userID], callingType: type)
} else if !groupID.isEmpty {
guard let pushVC = pushVC else { return }
self.launchCall(type: type, groupID: groupID, pushVC: pushVC, isClassic: false)
}
}
var result: [TUIExtensionInfo] = []
guard let filterVideoCall = param[TUICore_TUIChatExtension_NavigationMoreItem_FilterVideoCall] as? Bool else { return nil }
if !filterVideoCall {
let videoInfo = TUIExtensionInfo()
videoInfo.weight = 200
videoInfo.icon = TUICallKitCommon.getBundleImage(name: "video_call") ?? UIImage()
videoInfo.onClicked = { param in
onClick(param, .video)
}
result.append(videoInfo)
}
guard let filterAudioCall = param[TUICore_TUIChatExtension_NavigationMoreItem_FilterAudioCall] as? Bool else { return nil }
if !filterAudioCall {
let audioInfo = TUIExtensionInfo()
audioInfo.weight = 100
audioInfo.icon = TUICallKitCommon.getBundleImage(name: "audio_call") ?? UIImage()
audioInfo.onClicked = { param in
onClick(param, .audio)
}
result.append(audioInfo)
}
return result
}
func getInputViewMoreItemExtensionForClassicChat(param: [AnyHashable : Any]?) -> [TUIExtensionInfo]? {
guard let param = param else { return nil }
var result: [TUIExtensionInfo] = []
guard let filterVideoCall = param[TUICore_TUIChatExtension_InputViewMoreItem_FilterVideoCall] as? Bool else { return nil }
if !filterVideoCall {
let videoInfo = TUIExtensionInfo()
videoInfo.weight = 600
videoInfo.text = TUICoreDefineConvert.getTUIKitLocalizableString(key: "TUIKitMoreVideoCall")
videoInfo.icon = TUICoreDefineConvert.getTUICoreBundleThemeImage(imageKey: "service_more_video_call_img",
defaultImageName: "more_video_call")
videoInfo.onClicked = { param in
guard let param = param as? [String: Any] else { return }
self.doResponseInputViewExtension(param: param, type: .video, isClassic: true)
}
result.append(videoInfo)
}
guard let filterAudioCall = param[TUICore_TUIChatExtension_InputViewMoreItem_FilterAudioCall] as? Bool else { return nil }
if !filterAudioCall {
let audioInfo = TUIExtensionInfo()
audioInfo.weight = 500
audioInfo.text = TUICoreDefineConvert.getTUIKitLocalizableString(key: "TUIKitMoreVoiceCall")
audioInfo.icon = TUICoreDefineConvert.getTUICoreBundleThemeImage(imageKey: "service_more_voice_call_img",
defaultImageName: "more_voice_call")
audioInfo.onClicked = { param in
guard let param = param as? [String: Any] else { return }
self.doResponseInputViewExtension(param: param, type: .audio, isClassic: true)
}
result.append(audioInfo)
}
return result
}
func getFriendProfileActionMenuExtensionForClassicContact(param: [AnyHashable : Any]?) -> [TUIExtensionInfo]? {
guard let param = param else { return nil }
var result: [TUIExtensionInfo] = []
guard let filterVideoCall = param[TUICore_TUIContactExtension_FriendProfileActionMenu_FilterVideoCall] as? Bool else { return nil }
if !filterVideoCall {
let videoInfo = TUIExtensionInfo()
videoInfo.weight = 200
videoInfo.text = TUICoreDefineConvert.getTUIKitLocalizableString(key: "TUIKitMoreVideoCall")
videoInfo.onClicked = {[weak self] param in
guard let self = self else { return }
guard let userID = param[TUICore_TUIContactExtension_FriendProfileActionMenu_UserID] as? String else { return }
if !userID.isEmpty {
self.startCall(groupID: "", userIDs: [userID], callingType: .video)
}
}
result.append(videoInfo)
}
guard let filterAudioCall = param[TUICore_TUIContactExtension_FriendProfileActionMenu_FilterAudioCall] as? Bool else { return nil }
if !filterAudioCall {
let audioInfo = TUIExtensionInfo()
audioInfo.weight = 100
audioInfo.text = TUICoreDefineConvert.getTUIKitLocalizableString(key: "TUIKitMoreVoiceCall")
audioInfo.onClicked = {[weak self] param in
guard let self = self else { return }
guard let userID = param[TUICore_TUIContactExtension_FriendProfileActionMenu_UserID] as? String else { return }
if !userID.isEmpty {
self.startCall(groupID: "", userIDs: [userID], callingType: .audio)
}
}
result.append(audioInfo)
}
return result
}
func getFriendProfileActionMenuExtensionForMinimalistContact(param: [AnyHashable : Any]?) -> [TUIExtensionInfo]? {
guard let param = param else { return nil }
var result: [TUIExtensionInfo] = []
guard let filterVideoCall = param[TUICore_TUIContactExtension_FriendProfileActionMenu_FilterVideoCall] as? Bool else { return nil }
if !filterVideoCall {
let videoInfo = TUIExtensionInfo()
videoInfo.weight = 100
videoInfo.icon = TUICoreDefineConvert.getTUIDynamicImage(imageKey: "", module: TUIThemeModule.contact_Minimalist,
defaultImage: UIImage(named: TUICoreDefineConvert.getTUIContactImagePathMinimalist(imageName: "contact_info_video")) ?? UIImage())
videoInfo.text = TUICoreDefineConvert.getTIMCommonLocalizableString(key: "TUIKitVideo")
videoInfo.onClicked = {[weak self] param in
guard let self = self else { return }
guard let userID = param[TUICore_TUIContactExtension_FriendProfileActionMenu_UserID] as? String else { return }
if !userID.isEmpty {
self.startCall(groupID: "", userIDs: [userID], callingType: .video)
}
}
result.append(videoInfo)
}
guard let filterAudioCall = param[TUICore_TUIContactExtension_FriendProfileActionMenu_FilterAudioCall] as? Bool else { return nil }
if !filterAudioCall {
let audioInfo = TUIExtensionInfo()
audioInfo.weight = 200
audioInfo.icon = TUICoreDefineConvert.getTUIDynamicImage(imageKey: "", module: TUIThemeModule.contact_Minimalist,
defaultImage: UIImage(named: TUICoreDefineConvert.getTUIContactImagePathMinimalist(imageName: "contact_info_audio")) ?? UIImage())
audioInfo.text = TUICoreDefineConvert.getTIMCommonLocalizableString(key: "TUIKitAudio")
audioInfo.onClicked = {[weak self] param in
guard let self = self else { return }
guard let userID = param[TUICore_TUIContactExtension_FriendProfileActionMenu_UserID] as? String else { return }
if !userID.isEmpty {
self.startCall(groupID: "", userIDs: [userID], callingType: .audio)
}
}
result.append(audioInfo)
}
return result
}
func getGroupInfoCardActionMenuExtensionForMinimalistGroup(param: [AnyHashable : Any]?) -> [TUIExtensionInfo]? {
guard let param = param else { return nil }
var result: [TUIExtensionInfo] = []
guard let filterVideoCall = param[TUICore_TUIContactExtension_GroupInfoCardActionMenu_FilterVideoCall] as? Bool else { return nil }
if !filterVideoCall {
let videoInfo = TUIExtensionInfo()
videoInfo.weight = 100
videoInfo.icon = TUICoreDefineConvert.getTUIDynamicImage(imageKey: "", module: TUIThemeModule.contact_Minimalist,
defaultImage: UIImage(named: TUICoreDefineConvert.getTUIContactImagePathMinimalist(imageName: "contact_info_video")) ?? UIImage())
videoInfo.text = TUICoreDefineConvert.getTIMCommonLocalizableString(key: "TUIKitVideo")
videoInfo.onClicked = {[weak self] param in
guard let self = self else { return }
guard let pushVC = param[TUICore_TUIContactExtension_GroupInfoCardActionMenu_PushVC] as? UINavigationController else { return }
guard let groupID = param[TUICore_TUIContactExtension_GroupInfoCardActionMenu_GroupID] as? String else { return }
if !groupID.isEmpty {
self.launchCall(type: .video, groupID: groupID, pushVC: pushVC, isClassic: false)
}
}
result.append(videoInfo)
}
guard let filterAudioCall = param[TUICore_TUIContactExtension_GroupInfoCardActionMenu_FilterAudioCall] as? Bool else { return nil }
if !filterAudioCall {
let audioInfo = TUIExtensionInfo()
audioInfo.weight = 200
audioInfo.icon = TUICoreDefineConvert.getTUIDynamicImage(imageKey: "", module: TUIThemeModule.contact_Minimalist,
defaultImage: UIImage(named: TUICoreDefineConvert.getTUIContactImagePathMinimalist(imageName: "contact_info_audio")) ?? UIImage())
audioInfo.text = TUICoreDefineConvert.getTIMCommonLocalizableString(key: "TUIKitAudio")
audioInfo.onClicked = {[weak self] param in
guard let self = self else { return }
guard let pushVC = param[TUICore_TUIContactExtension_GroupInfoCardActionMenu_PushVC] as? UINavigationController else { return }
guard let groupID = param[TUICore_TUIContactExtension_GroupInfoCardActionMenu_GroupID] as? String else { return }
if !groupID.isEmpty {
self.launchCall(type: .audio, groupID: groupID, pushVC: pushVC, isClassic: false)
}
}
result.append(audioInfo)
}
return result
}
}