增加换肤功能
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
//
|
||||
// InviteToJoinRoomManager.swift
|
||||
// TUIRoomKit
|
||||
//
|
||||
// Created by janejntang on 2023/7/3.
|
||||
// You can choose to invite members and send invitations.
|
||||
|
||||
import Foundation
|
||||
import RTCRoomEngine
|
||||
import TUICore
|
||||
|
||||
class InviteToJoinRoomManager {
|
||||
class func startInviteToJoinRoom(message: RoomMessageModel, inviter: TUILoginUserInfo) {
|
||||
let inviteJoinModel = InviteJoinModel(message: message, inviter: inviter)
|
||||
pushSelectGroupMemberViewController(groupId: message.groupId) { responseData in
|
||||
guard let modelList =
|
||||
responseData[TUICore_TUIGroupObjectFactory_SelectGroupMemberVC_ResultUserList] as? [TUIUserModel]
|
||||
else { return }
|
||||
var invitedList: [String] = []
|
||||
for userModel in modelList {
|
||||
invitedList.append(userModel.userId)
|
||||
}
|
||||
inviteToJoinRoom(inviteJoinModel: inviteJoinModel, invitedList: invitedList)
|
||||
}
|
||||
}
|
||||
|
||||
class func pushSelectGroupMemberViewController(groupId: String, callback: @escaping TUIValueResultCallback) {
|
||||
let param = [TUICore_TUIGroupObjectFactory_SelectGroupMemberVC_GroupID: groupId]
|
||||
if let navigateController = RoomMessageManager.shared.navigateController {
|
||||
navigateController.push(TUICore_TUIGroupObjectFactory_SelectGroupMemberVC_Classic, param: param) { responseData in
|
||||
callback(responseData)
|
||||
}
|
||||
} else {
|
||||
let nav = UINavigationController()
|
||||
let currentViewController = getCurrentWindowViewController()
|
||||
currentViewController?.present(TUICore_TUIGroupObjectFactory_SelectGroupMemberVC_Classic,
|
||||
param: param, embbedIn: nav,
|
||||
forResult: { responseData in
|
||||
callback(responseData)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
class func inviteToJoinRoom(inviteJoinModel: InviteJoinModel, invitedList: [String]) {
|
||||
guard invitedList.count > 0 else { return }
|
||||
let dataDict = inviteJoinModel.getDicFromInviteJoinModel(inviteJoinModel: inviteJoinModel)
|
||||
guard let dataString = dataDict.convertToString() else { return }
|
||||
let pushInfo = V2TIMOfflinePushInfo()
|
||||
invitedList.forEach { userId in
|
||||
V2TIMManager.sharedInstance().invite(userId,
|
||||
data: dataString,
|
||||
onlineUserOnly: true,
|
||||
offlinePushInfo: pushInfo,
|
||||
timeout: 60) {
|
||||
debugPrint("invite,success")
|
||||
} fail: { code, message in
|
||||
debugPrint("invite,code:\(code),message:\(String(describing: message))")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class private func getCurrentWindowViewController() -> UIViewController? {
|
||||
var keyWindow: UIWindow?
|
||||
for window in UIApplication.shared.windows {
|
||||
if window.isMember(of: UIWindow.self), window.isKeyWindow {
|
||||
keyWindow = window
|
||||
break
|
||||
}
|
||||
}
|
||||
guard let rootController = keyWindow?.rootViewController else {
|
||||
return nil
|
||||
}
|
||||
func findCurrentController(from vc: UIViewController?) -> UIViewController? {
|
||||
if let nav = vc as? UINavigationController {
|
||||
return findCurrentController(from: nav.topViewController)
|
||||
} else if let tabBar = vc as? UITabBarController {
|
||||
return findCurrentController(from: tabBar.selectedViewController)
|
||||
} else if let presented = vc?.presentedViewController {
|
||||
return findCurrentController(from: presented)
|
||||
}
|
||||
return vc
|
||||
}
|
||||
let viewController = findCurrentController(from: rootController)
|
||||
return viewController
|
||||
}
|
||||
}
|
||||
125
TUIKit/TUIRoomKit/RoomExtension/Model/Manager/RoomManager.swift
Normal file
125
TUIKit/TUIRoomKit/RoomExtension/Model/Manager/RoomManager.swift
Normal file
@@ -0,0 +1,125 @@
|
||||
//
|
||||
// RoomManager.swift
|
||||
// TUIRoomKit
|
||||
//
|
||||
// Created by janejntang on 2023/7/3.
|
||||
// Manage rooms, including room creation, entry, exit, destruction and conversion operations of the host
|
||||
|
||||
import Foundation
|
||||
import RTCRoomEngine
|
||||
import TUICore
|
||||
|
||||
class RoomManager {
|
||||
static let shared = RoomManager()
|
||||
private var engineManager: EngineManager {
|
||||
EngineManager.shared
|
||||
}
|
||||
private var roomInfo: TUIRoomInfo {
|
||||
engineManager.store.roomInfo
|
||||
}
|
||||
private lazy var userId: String = {
|
||||
return TUILogin.getUserID() ?? engineManager.store.currentUser.userId
|
||||
}()
|
||||
private let messageManager = RoomMessageManager.shared
|
||||
let roomObserver: RoomObserver = RoomObserver()
|
||||
var roomId: String?
|
||||
|
||||
deinit {
|
||||
debugPrint("deinit \(self)")
|
||||
}
|
||||
|
||||
func isEnteredOtherRoom(roomId: String) -> Bool {
|
||||
return roomInfo.roomId != roomId && roomInfo.roomId != ""
|
||||
}
|
||||
|
||||
func createRoom(roomInfo: TUIRoomInfo) {
|
||||
roomId = roomInfo.roomId
|
||||
roomObserver.registerObserver()
|
||||
engineManager.createRoom(roomInfo: roomInfo) { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.roomObserver.createdRoom()
|
||||
self.enterRoom(roomId: roomInfo.roomId, isShownConferenceViewController: false)
|
||||
} onError: { _, message in
|
||||
RoomRouter.makeToast(toast: message)
|
||||
}
|
||||
}
|
||||
|
||||
func enterRoom(roomId: String, isShownConferenceViewController: Bool = true) {
|
||||
roomObserver.registerObserver()
|
||||
engineManager.store.isImAccess = true
|
||||
self.roomId = roomId
|
||||
engineManager.enterRoom(roomId: roomId, enableAudio: engineManager.store.isOpenMicrophone, enableVideo: engineManager.store.isOpenCamera, isSoundOnSpeaker: true) { [weak self] roomInfo in
|
||||
guard let self = self else { return }
|
||||
self.roomObserver.enteredRoom()
|
||||
guard isShownConferenceViewController else { return }
|
||||
let vc = ConferenceMainViewController()
|
||||
RoomRouter.shared.push(viewController: vc)
|
||||
} onError: { _, message in
|
||||
RoomRouter.makeToast(toast: message)
|
||||
}
|
||||
}
|
||||
|
||||
func exitRoom(onSuccess: @escaping TUISuccessBlock, onError: @escaping TUIErrorBlock) {
|
||||
engineManager.exitRoom { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.refreshSource()
|
||||
self.messageManager.isReadyToSendMessage = true
|
||||
onSuccess()
|
||||
} onError: { [weak self] code, message in
|
||||
guard let self = self else { return }
|
||||
self.refreshSource()
|
||||
if code.rawValue == -2_102 {
|
||||
self.destroyRoom(onSuccess: onSuccess, onError: onError)
|
||||
} else {
|
||||
onError(code, message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func destroyRoom(onSuccess: @escaping TUISuccessBlock, onError: @escaping TUIErrorBlock) {
|
||||
engineManager.destroyRoom { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.roomObserver.messageModel.roomState = .destroyed
|
||||
self.refreshSource()
|
||||
self.messageManager.isReadyToSendMessage = true
|
||||
onSuccess()
|
||||
} onError: { [weak self] code, message in
|
||||
guard let self = self else { return }
|
||||
self.refreshSource()
|
||||
onError(code, message)
|
||||
}
|
||||
}
|
||||
|
||||
private func refreshSource() {
|
||||
roomId = nil
|
||||
TUILogin.setCurrentBusinessScene(.None)
|
||||
roomObserver.userList = []
|
||||
roomObserver.unregisterObserver()
|
||||
}
|
||||
|
||||
private func changeUserRole(userId: String, role: TUIRole, onSuccess: @escaping TUISuccessBlock, onError: @escaping TUIErrorBlock) {
|
||||
engineManager.changeUserRole(userId: userId, role: .roomOwner) {
|
||||
onSuccess()
|
||||
} onError: { code, message in
|
||||
onError(code, message)
|
||||
}
|
||||
}
|
||||
|
||||
func exitOrDestroyPreviousRoom(onSuccess: @escaping TUISuccessBlock, onError: @escaping TUIErrorBlock) {
|
||||
if roomInfo.ownerId == userId {
|
||||
if let userModel = engineManager.store.attendeeList.first(where: { $0.userId != userId }) {
|
||||
changeUserRole(userId: userModel.userId, role: .roomOwner) { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.exitRoom(onSuccess: onSuccess, onError: onError)
|
||||
} onError: { [weak self] code, message in
|
||||
guard let self = self else { return }
|
||||
self.destroyRoom(onSuccess: onSuccess, onError: onError)
|
||||
}
|
||||
} else {
|
||||
destroyRoom(onSuccess: onSuccess, onError: onError)
|
||||
}
|
||||
} else {
|
||||
exitRoom(onSuccess: onSuccess, onError: onError)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
//
|
||||
// RoomMessageManager.swift
|
||||
// TUIRoomKit
|
||||
//
|
||||
// Created by janejntang on 2023/5/8.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
// Manage messages, including sending messages and modifying messages
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import TUICore
|
||||
import RTCRoomEngine
|
||||
|
||||
class RoomMessageManager: NSObject {
|
||||
static let shared = RoomMessageManager()
|
||||
private var engineManager: EngineManager {
|
||||
EngineManager.shared
|
||||
}
|
||||
private lazy var userId: String = {
|
||||
return TUILogin.getUserID() ?? engineManager.store.currentUser.userId
|
||||
}()
|
||||
weak var navigateController: UINavigationController?
|
||||
var isReadyToSendMessage: Bool = true
|
||||
var groupId: String = ""
|
||||
private override init() {
|
||||
super.init()
|
||||
TUICore.registerEvent(TUICore_TUIChatNotify, subKey: TUICore_TUIChatNotify_SendMessageSubKey, object: self)
|
||||
}
|
||||
|
||||
func sendRoomMessageToGroup() {
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
guard BusinessSceneUtil.canJoinRoom() else { return }
|
||||
if self.engineManager.store.isEnteredRoom {
|
||||
RoomManager.shared.exitOrDestroyPreviousRoom() { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.sendMessage()
|
||||
} onError: { [weak self] code, message in
|
||||
guard let self = self else { return }
|
||||
self.sendMessage()
|
||||
debugPrint("exitRoom,code:\(code),message:\(message)")
|
||||
}
|
||||
} else {
|
||||
self.sendMessage()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func sendMessage() {
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
guard self.isReadyToSendMessage else {
|
||||
self.changeReadyToSendMessage()
|
||||
return
|
||||
}
|
||||
self.isReadyToSendMessage = false
|
||||
FetchRoomId.getRoomId { [weak self] roomId in
|
||||
guard let self = self else { return }
|
||||
let messageModel = RoomMessageModel()
|
||||
messageModel.groupId = self.groupId
|
||||
messageModel.roomId = roomId
|
||||
messageModel.ownerName = TUILogin.getNickName() ?? ""
|
||||
messageModel.owner = self.userId
|
||||
let messageDic = messageModel.getDictFromMessageModel()
|
||||
guard let jsonString = messageDic.convertToString() else { return }
|
||||
let jsonData = jsonString.data(using: String.Encoding.utf8)
|
||||
let message = V2TIMManager.sharedInstance().createCustomMessage(jsonData)
|
||||
message?.supportMessageExtension = true
|
||||
let param = [TUICore_TUIChatService_SendMessageMethod_MsgKey: message]
|
||||
TUICore.callService(TUICore_TUIChatService, method: TUICore_TUIChatService_SendMessageMethod, param: param as [AnyHashable : Any])
|
||||
RoomManager.shared.roomId = roomId
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func resendRoomMessage(message: RoomMessageModel,dic:[String: Any]) {
|
||||
if message.messageId == "" {
|
||||
self.modifyMessage(message: message, dic: dic)
|
||||
return
|
||||
}
|
||||
V2TIMManager.sharedInstance().findMessages([message.messageId]) { [weak self] messageArray in
|
||||
guard let self = self else { return }
|
||||
guard let array = messageArray else { return }
|
||||
for previousMessage in array where previousMessage.msgID == message.messageId {
|
||||
self.modifyMessage(message: message, dic: dic)
|
||||
}
|
||||
} fail: { [weak self] code, messageString in
|
||||
guard let self = self else { return }
|
||||
self.modifyMessage(message: message, dic: dic)
|
||||
}
|
||||
}
|
||||
|
||||
private func modifyMessage(message: RoomMessageModel, dic:[String: Any]) {
|
||||
guard let message = message.getMessage() else { return }
|
||||
guard var customElemDic = TUITool.jsonData2Dictionary(message.customElem.data) as? [String: Any] else { return }
|
||||
for (key, value) in dic {
|
||||
customElemDic[key] = value
|
||||
}
|
||||
guard let jsonString = customElemDic.convertToString() else { return }
|
||||
let jsonData = jsonString.data(using: String.Encoding.utf8)
|
||||
message.customElem.data = jsonData
|
||||
V2TIMManager.sharedInstance().modifyMessage(message) { code, desc, msg in
|
||||
if code == 0 {
|
||||
debugPrint("modifyMessage,success")
|
||||
} else {
|
||||
debugPrint("modifyMessage,code:\(code),message:\(String(describing: desc))")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
deinit {
|
||||
debugPrint("deinit \(self)")
|
||||
}
|
||||
}
|
||||
|
||||
extension RoomMessageManager {
|
||||
private func changeReadyToSendMessage() {
|
||||
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 20) { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.isReadyToSendMessage = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension RoomMessageManager: TUINotificationProtocol {
|
||||
func onNotifyEvent(_ key: String, subKey: String, object anObject: Any?, param: [AnyHashable : Any]?) {
|
||||
guard key == TUICore_TUIChatNotify, subKey == TUICore_TUIChatNotify_SendMessageSubKey else { return }
|
||||
guard let code = param?[TUICore_TUIChatNotify_SendMessageSubKey_Code] as? Int, code == 0 else { return }
|
||||
guard let message = param?[TUICore_TUIChatNotify_SendMessageSubKey_Message] as? V2TIMMessage else { return }
|
||||
let messageModel = RoomMessageModel()
|
||||
messageModel.updateMessage(message: message)
|
||||
guard messageModel.messageId.count > 0, messageModel.roomState == .creating, messageModel.roomId == RoomManager.shared.roomId else { return }
|
||||
let roomInfo = TUIRoomInfo()
|
||||
roomInfo.roomId = messageModel.roomId
|
||||
RoomManager.shared.createRoom(roomInfo: roomInfo)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user