From 3a4df173d24b843c9cebfdd4087315c8e298ef98 Mon Sep 17 00:00:00 2001 From: Yu Sung Date: Mon, 30 Mar 2026 18:24:40 +0900 Subject: [PATCH] =?UTF-8?q?fix(live-room):=20=EC=8A=A4=ED=83=AD=20?= =?UTF-8?q?=ED=95=B4=EC=A0=9C=20=ED=9B=84=20=EB=B0=A9=20=EC=A0=95=EB=B3=B4?= =?UTF-8?q?=20=EA=B0=B1=EC=8B=A0=20=ED=83=80=EC=9D=B4=EB=B0=8D=EC=9D=84=20?= =?UTF-8?q?=EB=B3=B4=EC=A0=95=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/Live/Room/LiveRoomViewModel.swift | 18 ++++++++--- docs/20260330_라이브룸스탭해제갱신수정.md | 31 +++++++++++++++++++ 2 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 docs/20260330_라이브룸스탭해제갱신수정.md diff --git a/SodaLive/Sources/Live/Room/LiveRoomViewModel.swift b/SodaLive/Sources/Live/Room/LiveRoomViewModel.swift index 9832639..258823b 100644 --- a/SodaLive/Sources/Live/Room/LiveRoomViewModel.swift +++ b/SodaLive/Sources/Live/Room/LiveRoomViewModel.swift @@ -1055,9 +1055,12 @@ final class LiveRoomViewModel: NSObject, ObservableObject { agora.sendMessageToPeer(peerId: String(peerId), rawMessage: LiveRoomRequestType.CHANGE_LISTENER.rawValue.data(using: .utf8)!) { [unowned self] _, error in if error == nil { if isFromManager { - getRoomInfo() - setManagerMessage() releaseManagerMessageToPeer(userId: peerId) + + DispatchQueue.main.asyncAfter(deadline: .now() + 0.8) { [weak self] in + self?.getRoomInfo() + } + self.popupContent = "\(getUserNicknameAndProfileUrl(accountId: peerId).nickname)님을 스탭에서 해제했어요." } else { self.popupContent = "\(getUserNicknameAndProfileUrl(accountId: peerId).nickname)님을 리스너로 변경했어요." @@ -1101,7 +1104,10 @@ final class LiveRoomViewModel: NSObject, ObservableObject { } func setListener() { - repository.setListener(roomId: AppState.shared.roomId, userId: UserDefaults.int(forKey: .userId)) + let currentUserId = UserDefaults.int(forKey: .userId) + let wasManager = liveRoomInfo?.managerList.contains(where: { $0.id == currentUserId }) ?? false + + repository.setListener(roomId: AppState.shared.roomId, userId: currentUserId) .sink { result in switch result { case .finished: @@ -1121,10 +1127,14 @@ final class LiveRoomViewModel: NSObject, ObservableObject { self.agora.setRole(role: .audience) self.isMute = false self.agora.mute(isMute) - if let index = self.muteSpeakers.firstIndex(of: UInt(UserDefaults.int(forKey: .userId))) { + if let index = self.muteSpeakers.firstIndex(of: UInt(currentUserId)) { self.muteSpeakers.remove(at: index) } self.getRoomInfo() + + if wasManager { + self.setManagerMessage() + } } } catch { } diff --git a/docs/20260330_라이브룸스탭해제갱신수정.md b/docs/20260330_라이브룸스탭해제갱신수정.md new file mode 100644 index 0000000..01134bd --- /dev/null +++ b/docs/20260330_라이브룸스탭해제갱신수정.md @@ -0,0 +1,31 @@ +# 20260330 라이브룸 스탭 해제 갱신 수정 + +## 작업 개요 +- 라이브 진행 중 스탭 지정/해제 시 `LiveRoomProfilesDialogView`의 스탭 표시가 실시간으로 정확히 갱신되도록 원인 분석 및 수정한다. + +## 구현 체크리스트 +- [x] 관련 코드 경로 병렬 탐색(Explore + 직접 검색)으로 원인 확정 +- [x] 스탭 해제 동작 시 서버/클라이언트 상태 갱신 누락 수정 +- [x] `LiveRoomProfilesDialogView`에 전달되는 `roomInfo` 재조회 타이밍 보정 +- [x] 변경 파일 진단 및 빌드 검증 수행 +- [x] 검증 기록 누적 + +## 검증 기록 +- 무엇: 스탭 해제 시점에 방장 클라이언트가 너무 이른 시점에만 `getRoomInfo()`를 호출해 `managerList`가 stale 상태로 남는 문제를 수정. +- 왜: `LiveRoomProfilesDialogView`는 전달받은 `roomInfo.managerList`를 표시하므로, 해제 완료 이후의 최신 `roomInfo` 재조회 트리거가 필요. +- 어떻게: + - `LiveRoomViewModel.changeListener(peerId:isFromManager:)`에서 스탭 해제 시 즉시 `setManagerMessage()`를 보내던 흐름을 제거하고, 해제 안내 메시지 전송 후 지연 재조회(`DispatchQueue.main.asyncAfter`)를 추가. + - `LiveRoomViewModel.setListener()`에서 현재 사용자가 해제 대상 스탭이었던 경우(`wasManager`)에 `setManagerMessage()`를 전파해, 실제 해제 완료 이후 전체 클라이언트가 `getRoomInfo()`를 재호출하도록 보강. + +- 실행 명령 및 결과: + - `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug build` → `** BUILD SUCCEEDED **` + - `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug build` → `** BUILD SUCCEEDED **` + - `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" test` → `Scheme SodaLive is not currently configured for the test action.` + - `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" test` → `Scheme SodaLive-dev is not currently configured for the test action.` + - `lsp_diagnostics(LiveRoomViewModel.swift)` → `No such module 'Moya'` (로컬 SourceKit 모듈 해석 환경 이슈로 확인됨) + +- 수동 QA 시나리오(디바이스/시뮬레이터): + 1. 방장이 스피커/리스너를 스탭으로 지정한다. + 2. `LiveRoomProfilesDialogView`에서 스탭 섹션에 즉시 반영되는지 확인한다. + 3. 동일 사용자를 스탭 해제한다. + 4. 다이얼로그를 닫지 않은 상태에서도 스탭 섹션에서 제거되는지 확인한다.