diff --git a/SodaLive/Sources/Chat/Talk/Room/ChatRoomView.swift b/SodaLive/Sources/Chat/Talk/Room/ChatRoomView.swift index c4c634b..ce63ca2 100644 --- a/SodaLive/Sources/Chat/Talk/Room/ChatRoomView.swift +++ b/SodaLive/Sources/Chat/Talk/Room/ChatRoomView.swift @@ -125,7 +125,7 @@ struct ChatRoomView: View { let message = viewModel.messages[index] if message.mine { UserMessageItemView(message: message) - .id(index) + .id("msg_\(index)") } else { AiMessageItemView( message: message, @@ -138,7 +138,7 @@ struct ChatRoomView: View { viewModel.selectedMessageIndex = index } } - .id(index) + .id("msg_\(index)") } } @@ -146,11 +146,11 @@ struct ChatRoomView: View { ChatQuotaNoticeItemView(remainingTime: viewModel.countdownText) { viewModel.purchaseChatQuota() } - .id(viewModel.messages.count) + .id("quota_\(viewModel.messages.count)") .padding(.bottom, 12) .onAppear { withAnimation(.easeOut(duration: 0.3)) { - proxy.scrollTo(viewModel.messages.count, anchor: .bottom) + proxy.scrollTo("quota_\(viewModel.messages.count)", anchor: .bottom) } } } @@ -160,22 +160,19 @@ struct ChatRoomView: View { characterName: viewModel.characterName, characterProfileUrl: viewModel.characterProfileUrl ) - .id(viewModel.messages.count) + .id("typing_\(viewModel.messages.count)") } } .padding(.horizontal, 24) .frame(minHeight: geometry.size.height, alignment: .bottom) } .onChange(of: viewModel.messages.count) { _ in - if !viewModel.messages.isEmpty { - withAnimation(.easeOut(duration: 0.3)) { - proxy.scrollTo( - viewModel.showSendingMessage ? - viewModel.messages.count : - viewModel.messages.count - 1, - anchor: .bottom - ) - } + guard !viewModel.messages.isEmpty else { return } + withAnimation(.easeOut(duration: 0.3)) { + let targetId = viewModel.showSendingMessage + ? "typing_\(viewModel.messages.count)" + : "msg_\(viewModel.messages.count - 1)" + proxy.scrollTo(targetId, anchor: .bottom) } } } diff --git a/SodaLive/Sources/Chat/Talk/Room/ChatRoomViewModel.swift b/SodaLive/Sources/Chat/Talk/Room/ChatRoomViewModel.swift index 4603567..4db4a36 100644 --- a/SodaLive/Sources/Chat/Talk/Room/ChatRoomViewModel.swift +++ b/SodaLive/Sources/Chat/Talk/Room/ChatRoomViewModel.swift @@ -151,6 +151,7 @@ final class ChatRoomViewModel: ObservableObject { roomId: roomId, characterImageId: self.chatRoomBgImageId ) + .receive(on: DispatchQueue.main) .sink { result in switch result { case .finished: @@ -200,6 +201,7 @@ final class ChatRoomViewModel: ObservableObject { func getMemberInfo() { userRepository.getMemberInfo() + .receive(on: DispatchQueue.main) .sink { result in switch result { case .finished: @@ -233,6 +235,7 @@ final class ChatRoomViewModel: ObservableObject { isLoading = true repository.purchaseMessage(roomId: roomId, messageId: selectedMessage.messageId) + .receive(on: DispatchQueue.main) .sink { result in switch result { case .finished: @@ -277,6 +280,7 @@ final class ChatRoomViewModel: ObservableObject { isLoading = true repository.purchaseChatQuota(roomId: roomId) + .receive(on: DispatchQueue.main) .sink { result in switch result { case .finished: @@ -320,6 +324,7 @@ final class ChatRoomViewModel: ObservableObject { isResetting = true repository.resetChatRoom(roomId: roomId) + .receive(on: DispatchQueue.main) .sink { result in switch result { case .finished: