269 lines
10 KiB
Swift
269 lines
10 KiB
Swift
|
|
//
|
||
|
|
// RoomStore.swift
|
||
|
|
// TUIRoomKit
|
||
|
|
//
|
||
|
|
// Created by aby on 2022/12/28.
|
||
|
|
// Copyright © 2022 Tencent. All rights reserved.
|
||
|
|
//
|
||
|
|
|
||
|
|
import Foundation
|
||
|
|
import TUICore
|
||
|
|
import RTCRoomEngine
|
||
|
|
import Factory
|
||
|
|
|
||
|
|
let roomHashNumber: Int = 0x3B9AC9FF
|
||
|
|
|
||
|
|
class RoomStore: NSObject {
|
||
|
|
var currentUser: UserEntity = UserEntity()
|
||
|
|
var roomInfo: TUIRoomInfo = TUIRoomInfo()
|
||
|
|
var videoSetting: VideoModel = VideoModel()
|
||
|
|
var audioSetting: AudioModel = AudioModel()
|
||
|
|
var attendeeList: [UserEntity] = [] // User list
|
||
|
|
var seatList: [UserEntity] = [] // List of users who have taken the stage
|
||
|
|
var offSeatList: [UserEntity] = [] // List of users who not on stage
|
||
|
|
var inviteSeatList: [RequestEntity] = [] // List of users who apply to be on stage
|
||
|
|
var isEnteredRoom: Bool = false
|
||
|
|
var timeStampOnEnterRoom: Int = 0 // Timestamp of entering the meeting
|
||
|
|
var isImAccess: Bool = false // Whether TUIRoomKit is entered by IM
|
||
|
|
var selfTakeSeatRequestId: String? // Self ID for applying on stage
|
||
|
|
var shouldShowFloatChatView = true
|
||
|
|
private let openCameraKey = "isOpenCamera"
|
||
|
|
private let openMicrophoneKey = "isOpenMicrophone"
|
||
|
|
private let shownRaiseHandNoticeKey = "isShownRaiseHandNotice"
|
||
|
|
weak var conferenceObserver: ConferenceObserver?
|
||
|
|
|
||
|
|
var isOpenMicrophone: Bool {
|
||
|
|
didSet {
|
||
|
|
UserDefaults.standard.set(isOpenMicrophone, forKey: openMicrophoneKey)
|
||
|
|
UserDefaults.standard.synchronize()
|
||
|
|
}
|
||
|
|
}
|
||
|
|
var isOpenCamera: Bool {
|
||
|
|
didSet {
|
||
|
|
UserDefaults.standard.set(isOpenCamera, forKey: openCameraKey)
|
||
|
|
UserDefaults.standard.synchronize()
|
||
|
|
}
|
||
|
|
}
|
||
|
|
var isShownRaiseHandNotice: Bool {
|
||
|
|
didSet {
|
||
|
|
UserDefaults.standard.set(isShownRaiseHandNotice, forKey: shownRaiseHandNoticeKey)
|
||
|
|
UserDefaults.standard.synchronize()
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
override init() {
|
||
|
|
if let isOpenMicrophoneValue = UserDefaults.standard.object(forKey: openMicrophoneKey) as? Bool {
|
||
|
|
isOpenMicrophone = isOpenMicrophoneValue
|
||
|
|
} else {
|
||
|
|
isOpenMicrophone = true
|
||
|
|
}
|
||
|
|
if let isOpenCameraValue = UserDefaults.standard.object(forKey: openCameraKey) as? Bool {
|
||
|
|
isOpenCamera = isOpenCameraValue
|
||
|
|
} else {
|
||
|
|
isOpenCamera = true
|
||
|
|
}
|
||
|
|
if let isShownRaiseHandNoticeValue = UserDefaults.standard.object(forKey: shownRaiseHandNoticeKey) as? Bool {
|
||
|
|
isShownRaiseHandNotice = isShownRaiseHandNoticeValue
|
||
|
|
} else {
|
||
|
|
isShownRaiseHandNotice = true
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func initialRoomInfo(_ roomInfo: TUIRoomInfo) {
|
||
|
|
self.roomInfo = roomInfo
|
||
|
|
EngineEventCenter.shared.notifyEngineEvent(event: .onInitialRoomInfo, param: ["roomInfo": roomInfo])
|
||
|
|
}
|
||
|
|
|
||
|
|
func initalEnterRoomMessage() {
|
||
|
|
isEnteredRoom = true
|
||
|
|
timeStampOnEnterRoom = Int(Date().timeIntervalSince1970)
|
||
|
|
}
|
||
|
|
|
||
|
|
func initialRoomCurrentUser() {
|
||
|
|
currentUser.userId = TUILogin.getUserID() ?? ""
|
||
|
|
currentUser.userName = TUILogin.getNickName() ?? ""
|
||
|
|
EngineManager.shared.getUserInfo(currentUser.userId) { [weak self] userInfo in
|
||
|
|
guard let self = self else { return }
|
||
|
|
guard let userInfo = userInfo else { return }
|
||
|
|
self.currentUser.update(userInfo: userInfo)
|
||
|
|
EngineEventCenter.shared.notifyEngineEvent(event: .onInitialSelfUserInfo, param: [:])
|
||
|
|
} onError: { code, message in
|
||
|
|
debugPrint("getUserInfo,code:\(code),message:\(message)")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func initialSeatList(seatList: [TUISeatInfo]) {
|
||
|
|
var localSeatList = [UserEntity]()
|
||
|
|
for seatInfo in seatList {
|
||
|
|
guard let userId = seatInfo.userId, userId != "" else { continue }
|
||
|
|
guard let userModel = getUserItem(userId) else { continue }
|
||
|
|
userModel.isOnSeat = true
|
||
|
|
localSeatList.append(userModel)
|
||
|
|
}
|
||
|
|
self.seatList = localSeatList
|
||
|
|
if seatList.contains(where: { $0.userId == currentUser.userId }) {
|
||
|
|
updateSelfOnSeatState(isOnSeat: true)
|
||
|
|
}
|
||
|
|
EngineEventCenter.shared.notifyUIEvent(key: .TUIRoomKitService_RenewSeatList, param: [:])
|
||
|
|
EngineEventCenter.shared.notifyUIEvent(key: .TUIRoomKitService_RenewVideoSeatView, param: [:])
|
||
|
|
}
|
||
|
|
|
||
|
|
func initialOffSeatList() {
|
||
|
|
offSeatList = attendeeList.filter({ !$0.isOnSeat })
|
||
|
|
}
|
||
|
|
|
||
|
|
func updateSelfOnSeatState(isOnSeat: Bool) {
|
||
|
|
currentUser.isOnSeat = isOnSeat
|
||
|
|
EngineEventCenter.shared.notifyUIEvent(key: .TUIRoomKitService_UserOnSeatChanged, param: ["isOnSeat": isOnSeat])
|
||
|
|
}
|
||
|
|
|
||
|
|
func updateUserDisableSendingMessage(userId: String, isDisable: Bool) {
|
||
|
|
if userId == currentUser.userId {
|
||
|
|
currentUser.disableSendingMessage = isDisable
|
||
|
|
}
|
||
|
|
guard let userItem = getUserItem(userId) else { return }
|
||
|
|
userItem.disableSendingMessage = isDisable
|
||
|
|
}
|
||
|
|
|
||
|
|
func deleteTakeSeatRequest(requestId: String) {
|
||
|
|
let requestUserId = inviteSeatList.first(where: { $0.requestId == requestId })?.userId
|
||
|
|
inviteSeatList = inviteSeatList.filter { requestItem in
|
||
|
|
requestItem.requestId != requestId
|
||
|
|
}
|
||
|
|
EngineEventCenter.shared.notifyEngineEvent(event: .onDeletedTakeSeatRequest, param: ["userId": requestUserId ?? ""])
|
||
|
|
EngineEventCenter.shared.notifyUIEvent(key: .TUIRoomKitService_RenewSeatList, param: [:])
|
||
|
|
}
|
||
|
|
|
||
|
|
func deleteInviteSeatUser(_ userId: String) {
|
||
|
|
inviteSeatList = inviteSeatList.filter { requestItem in
|
||
|
|
requestItem.userId != userId
|
||
|
|
}
|
||
|
|
EngineEventCenter.shared.notifyUIEvent(key: .TUIRoomKitService_RenewSeatList, param: [:])
|
||
|
|
}
|
||
|
|
|
||
|
|
func addInviteSeatUser(request: TUIRequest) {
|
||
|
|
guard !inviteSeatList.contains(where: { $0.userId == request.userId }) else { return }
|
||
|
|
let requestEntity = RequestEntity(requestId: request.requestId, userId: request.userId)
|
||
|
|
inviteSeatList.append(requestEntity)
|
||
|
|
EngineEventCenter.shared.notifyUIEvent(key: .TUIRoomKitService_RenewSeatList, param: [:])
|
||
|
|
}
|
||
|
|
|
||
|
|
func setCameraOpened(_ isCameraOpened: Bool) {
|
||
|
|
videoSetting.isCameraOpened = isCameraOpened
|
||
|
|
}
|
||
|
|
|
||
|
|
func setSoundOnSpeaker(_ isSoundOnSpeaker: Bool) {
|
||
|
|
audioSetting.isSoundOnSpeaker = isSoundOnSpeaker
|
||
|
|
}
|
||
|
|
|
||
|
|
func setConferenceObserver(_ observer: ConferenceObserver?) {
|
||
|
|
conferenceObserver = observer
|
||
|
|
}
|
||
|
|
|
||
|
|
func setInviteSeatList(list: [TUIRequest]) {
|
||
|
|
inviteSeatList = []
|
||
|
|
for request in list {
|
||
|
|
let requestEntity = RequestEntity(requestId: request.requestId, userId: request.userId)
|
||
|
|
inviteSeatList.append(requestEntity)
|
||
|
|
}
|
||
|
|
EngineEventCenter.shared.notifyUIEvent(key: .TUIRoomKitService_RenewSeatList, param: [:])
|
||
|
|
}
|
||
|
|
|
||
|
|
func updateLeftSeatList(leftList: [TUISeatInfo]) {
|
||
|
|
guard leftList.count > 0 else { return }
|
||
|
|
if leftList.contains(where: { $0.userId == currentUser.userId }) {
|
||
|
|
currentUser.isOnSeat = false
|
||
|
|
audioSetting.isMicOpened = false
|
||
|
|
EngineEventCenter.shared.notifyUIEvent(key: .TUIRoomKitService_UserOnSeatChanged,
|
||
|
|
param: ["isOnSeat":false])
|
||
|
|
}
|
||
|
|
for seatInfo: TUISeatInfo in leftList {
|
||
|
|
guard let userId = seatInfo.userId else { continue }
|
||
|
|
if let userItem = attendeeList.first(where: { $0.userId == userId }) {
|
||
|
|
userItem.isOnSeat = false
|
||
|
|
addOffSeatItem(userItem)
|
||
|
|
}
|
||
|
|
deleteOnSeatItem(userId)
|
||
|
|
}
|
||
|
|
EngineEventCenter.shared.notifyUIEvent(key: .TUIRoomKitService_RenewSeatList, param: [:])
|
||
|
|
}
|
||
|
|
|
||
|
|
func updateSeatedList(seatList: [TUISeatInfo]) {
|
||
|
|
guard seatList.count > 0 else { return }
|
||
|
|
if seatList.contains(where: { $0.userId == currentUser.userId }) {
|
||
|
|
currentUser.isOnSeat = true
|
||
|
|
EngineEventCenter.shared.notifyUIEvent(key: .TUIRoomKitService_UserOnSeatChanged,
|
||
|
|
param: ["isOnSeat":true])
|
||
|
|
}
|
||
|
|
for seatInfo: TUISeatInfo in seatList {
|
||
|
|
guard let userId = seatInfo.userId else { continue }
|
||
|
|
guard let userInfo = attendeeList.first(where: { $0.userId == userId }) else { continue }
|
||
|
|
userInfo.isOnSeat = true
|
||
|
|
addOnSeatItem(userInfo)
|
||
|
|
deleteOffSeatItem(userId)
|
||
|
|
}
|
||
|
|
EngineEventCenter.shared.notifyUIEvent(key: .TUIRoomKitService_RenewSeatList, param: [:])
|
||
|
|
}
|
||
|
|
|
||
|
|
func remoteUserEnterRoom(userInfo: TUIUserInfo) {
|
||
|
|
let userItem = UserEntity()
|
||
|
|
userItem.update(userInfo: userInfo)
|
||
|
|
addUserItem(userItem)
|
||
|
|
if roomInfo.isSeatEnabled, !userItem.isOnSeat {
|
||
|
|
addOffSeatItem(userItem)
|
||
|
|
}
|
||
|
|
EngineEventCenter.shared.notifyUIEvent(key: .TUIRoomKitService_RenewUserList, param: [:])
|
||
|
|
}
|
||
|
|
|
||
|
|
func remoteUserLeaveRoom(userInfo: TUIUserInfo) {
|
||
|
|
deleteUserItem(userInfo.userId)
|
||
|
|
deleteOffSeatItem(userInfo.userId)
|
||
|
|
EngineEventCenter.shared.notifyUIEvent(key: .TUIRoomKitService_RenewUserList, param: [:])
|
||
|
|
}
|
||
|
|
|
||
|
|
func updateFloatChatShowState(shouldShow: Bool) {
|
||
|
|
shouldShowFloatChatView = shouldShow
|
||
|
|
EngineEventCenter.shared.notifyUIEvent(key: .TUIRoomKitService_ShowFloatChatView, param: ["shouldShow": shouldShow])
|
||
|
|
}
|
||
|
|
|
||
|
|
deinit {
|
||
|
|
debugPrint("self:\(self),deinit")
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
extension RoomStore {
|
||
|
|
private func getUserItem(_ userId: String) -> UserEntity? {
|
||
|
|
return attendeeList.first(where: {$0.userId == userId})
|
||
|
|
}
|
||
|
|
|
||
|
|
private func addUserItem(_ userItem: UserEntity) {
|
||
|
|
guard getUserItem(userItem.userId) == nil else { return }
|
||
|
|
if userItem.userName.isEmpty {
|
||
|
|
userItem.userName = userItem.userId
|
||
|
|
}
|
||
|
|
attendeeList.append(userItem)
|
||
|
|
}
|
||
|
|
|
||
|
|
private func deleteUserItem(_ userId: String) {
|
||
|
|
attendeeList.removeAll(where: { $0.userId == userId })
|
||
|
|
}
|
||
|
|
|
||
|
|
private func addOnSeatItem(_ userItem: UserEntity) {
|
||
|
|
guard !seatList.contains(where: { $0.userId == userItem.userId }) else { return }
|
||
|
|
seatList.append(userItem)
|
||
|
|
}
|
||
|
|
|
||
|
|
private func deleteOnSeatItem(_ userId: String) {
|
||
|
|
seatList.removeAll(where: { $0.userId == userId })
|
||
|
|
}
|
||
|
|
|
||
|
|
private func addOffSeatItem(_ userItem: UserEntity) {
|
||
|
|
guard !offSeatList.contains(where: { $0.userId == userItem.userId }) else { return }
|
||
|
|
offSeatList.append(userItem)
|
||
|
|
}
|
||
|
|
|
||
|
|
private func deleteOffSeatItem(_ userId: String) {
|
||
|
|
offSeatList.removeAll(where: { $0.userId == userId })
|
||
|
|
}
|
||
|
|
}
|