增加换肤功能

This commit is contained in:
启星
2025-08-14 10:07:49 +08:00
parent f6964c1e89
commit 4f9318d98e
8789 changed files with 978530 additions and 2 deletions

View File

@@ -0,0 +1,47 @@
//
// ChatExtensionRoomSettingsViewModel.swift
// TUIRoomKit
//
// Created by janejntang on 2023/6/26.
//
import Foundation
class ChatExtensionRoomSettingsViewModel {
var isOpenMicrophone: Bool
var isOpenCamera: Bool
private let engineManager = EngineManager.shared
private(set) var roomSettingsViewItems: [RoomSetListItemData] = []
init(isOpenMicrophone: Bool, isOpenCamera: Bool) {
self.isOpenMicrophone = isOpenMicrophone
self.isOpenCamera = isOpenCamera
createRoomSettingsModel()
}
func createRoomSettingsModel() {
let openMicItem = RoomSetListItemData()
openMicItem.titleText = .micSeatText
openMicItem.isSwitchOn = isOpenMicrophone
openMicItem.action = {[weak self] sender in
guard let self = self, let view = sender as? UISwitch else { return }
self.engineManager.store.isOpenMicrophone = view.isOn
}
roomSettingsViewItems.append(openMicItem)
let openCameraItem = RoomSetListItemData()
openCameraItem.titleText = .cameraSetText
openCameraItem.isSwitchOn = isOpenCamera
openCameraItem.action = {[weak self] sender in
guard let self = self, let view = sender as? UISwitch else { return }
self.engineManager.store.isOpenCamera = view.isOn
}
roomSettingsViewItems.append(openCameraItem)
}
}
private extension String {
static var cameraSetText: String {
localized("Join the meeting and start the camera")
}
static var micSeatText: String {
localized("Join the conference and turn on the mic")
}
}

View File

@@ -0,0 +1,95 @@
//
// RoomaInviteViewModel.swift
// TUIRoomKit
//
// Created by janejntang on 2023/5/24.
// Copyright © 2023 Tencent. All rights reserved.
//
import Foundation
import TUICore
import AVFAudio
class InvitedToJoinRoomViewModel: NSObject, AVAudioPlayerDelegate {
let inviteUserName: String
let roomId: String
var avatarUrl: String
var displayLink: CADisplayLink?
var audioPlayer: AVAudioPlayer = AVAudioPlayer()
var startTime: TimeInterval?
var endTime: TimeInterval?
var messageManager: RoomMessageManager {
return RoomMessageManager.shared
}
private var roomManager: RoomManager {
RoomManager.shared
}
init(inviteUserName: String, inviteUserAvatarUrl: String, roomId: String) {
self.inviteUserName = inviteUserName
self.roomId = roomId
avatarUrl = inviteUserAvatarUrl
super.init()
playAudio(forResource: "phone_ringing", ofType: "mp3")
}
func startPlay() {
audioPlayer.play()
}
func stopPlay() {
audioPlayer.stop()
}
func disagreeAction() {
stopPlay()
closeInvitedToJoinRoomView()
}
func agreeAction() {
stopPlay()
if EngineManager.shared.store.isEnteredRoom {
roomManager.exitOrDestroyPreviousRoom { [weak self] in
guard let self = self else { return }
self.enterRoom()
} onError: { code, message in
debugPrint("exitRoom, code:\(code), message:\(message)")
}
} else {
enterRoom()
}
}
private func enterRoom() {
roomManager.enterRoom(roomId: roomId)
closeInvitedToJoinRoomView()
}
private func playAudio(forResource: String, ofType: String){
if let bundlePath = Bundle.main.path(forResource: forResource, ofType: ofType) {
let url = URL(fileURLWithPath: bundlePath)
do {
try AVAudioSession.sharedInstance().overrideOutputAudioPort(.speaker)
} catch let error {
debugPrint("AVAudioSession set outputAudioPort error:\(error.localizedDescription)")
}
do {
try audioPlayer = AVAudioPlayer(contentsOf: url)
audioPlayer.numberOfLoops = -1
audioPlayer.delegate = self
audioPlayer.prepareToPlay()
} catch let error {
debugPrint("audioPlayer error: \(error.localizedDescription)")
}
}
}
private func closeInvitedToJoinRoomView() {
TUIRoomImAccessService.shared.inviteWindow?.isHidden = true
TUIRoomImAccessService.shared.inviteWindow = nil
TUIRoomImAccessService.shared.isShownInvitedToJoinRoomView = false
}
deinit {
debugPrint("deinit \(self)")
}
}

View File

@@ -0,0 +1,59 @@
//
// RoomMsgViewModel.swift
// TUIRoomKit
//
// Created by janejntang on 2023/5/8.
// Copyright © 2023 Tencent. All rights reserved.
//
import Foundation
import TIMCommon
import TUICore
import RTCRoomEngine
@objc(RoomMessageBubbleCellData)
class RoomMessageBubbleCellData: TUIBubbleMessageCellData {
var messageModel: RoomMessageModel?
override init(direction: TMsgDirection) {
super.init(direction: direction)
}
override class func getCellData(_ message: V2TIMMessage) -> TUIMessageCellData {
let messageModel = RoomMessageModel()
messageModel.updateMessage(message: message)
if messageModel.roomId == RoomManager.shared.roomId, messageModel.roomState != .destroyed {
RoomManager.shared.roomObserver.messageModel.updateMessage(message: message)
}
let messageCellData = RoomMessageBubbleCellData(direction: message.isSelf ? .MsgDirectionOutgoing : .MsgDirectionIncoming)
messageCellData.messageModel = messageModel
return messageCellData
}
override class func getDisplayString(_ message: V2TIMMessage) -> String {
let businessID = parseBusinessID(message: message)
if businessID == BussinessID_GroupRoomMessage {
let dict = TUITool.jsonData2Dictionary(message.customElem.data) as? [String: Any]
let userName = dict?["ownerName"] as? String ?? ""
return userName + .quickMeetingText
} else {
return super.getDisplayString(message)
}
}
private class func parseBusinessID(message: V2TIMMessage?) -> String {
guard let message = message else { return "" }
let customData = message.customElem.data
let dict = TUITool.jsonData2Dictionary(customData)
guard let businessID = dict?["businessID"] as? String else { return ""}
return businessID
}
deinit {
debugPrint("deinit \(self)")
}
}
private extension String {
static var quickMeetingText: String {
localized("'s quick meeting")
}
}

View File

@@ -0,0 +1,96 @@
//
// RoomMessageViewModel.swift
// TUIRoomKit
//
// Created by janejntang on 2023/5/10.
// Copyright © 2023 Tencent. All rights reserved.
//
import Foundation
import RTCRoomEngine
import TUICore
import TIMCommon
protocol RoomMessageViewResponder: NSObject {
func updateStackView()
func updateRoomStatus()
func updateEnteredRoom()
func updateExitRoom()
}
class RoomMessageViewModel: NSObject {
var message: RoomMessageModel
private var engineManager: EngineManager {
EngineManager.shared
}
lazy var userId: String = {
return TUILogin.getUserID() ?? EngineManager.shared.store.currentUser.userId
}()
var messageManager: RoomMessageManager {
RoomMessageManager.shared
}
let roomManager = RoomManager.shared
weak var viewResponder: RoomMessageViewResponder?
init(message: RoomMessageModel) {
self.message = message
super.init()
roomManager.roomObserver.addListener(listener: self)
}
deinit {
roomManager.roomObserver.removeListener(listener: self)
debugPrint("deinit \(self)")
}
func changeMessage(message: RoomMessageModel) {
self.message = message
viewResponder?.updateStackView()
viewResponder?.updateRoomStatus()
}
func enterRoomAction() {
guard BusinessSceneUtil.canJoinRoom() else { return }
if roomManager.isEnteredOtherRoom(roomId: message.roomId) {
roomManager.exitOrDestroyPreviousRoom { [weak self] in
guard let self = self else { return }
self.enterRoom()
} onError: { [weak self] code, message in
debugPrint("exitRoom,code:\(code),message:\(message)")
guard let self = self else { return }
self.enterRoom()
}
} else {
enterRoom()
}
}
private func enterRoom() {
if !engineManager.store.isEnteredRoom {
roomManager.enterRoom(roomId: message.roomId)
} else {
EngineEventCenter.shared.notifyUIEvent(key: .TUIRoomKitService_ShowRoomMainView, param: [:])
}
}
func inviteUserAction() {
guard message.groupId.count > 0 else { return }
let inviter = TUILoginUserInfo()
inviter.userId = userId
inviter.userName = TUILogin.getNickName() ?? ""
inviter.avatarUrl = TUILogin.getFaceUrl() ?? ""
InviteToJoinRoomManager.startInviteToJoinRoom(message: message, inviter: inviter)
}
}
extension RoomMessageViewModel: RoomObserverListener {
func onRoomEnter(messageId: String, code: Int, message: String) {
if code == 0, messageId == self.message.messageId {
viewResponder?.updateEnteredRoom()
}
}
func onRoomExit(messageId: String) {
if messageId == self.message.messageId {
viewResponder?.updateExitRoom()
}
}
}