Files
featherVoice/TUIKit/TUIRoomKit/RoomExtension/Model/Manager/RoomManager.swift
2025-08-08 10:49:36 +08:00

126 lines
4.7 KiB
Swift

//
// 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)
}
}
}