feat(creator): 대화하기 액션을 연결한다

This commit is contained in:
Yu Sung
2026-07-03 18:13:04 +09:00
parent 3f24788c29
commit 37c34ae91e
13 changed files with 242 additions and 24 deletions

View File

@@ -1,13 +1,22 @@
import SwiftUI
import Bootpay
import BootpayUI
struct CreatorChannelView: View {
let creatorId: Int
@StateObject private var viewModel = CreatorChannelViewModel()
@StateObject private var channelDonationViewModel = ChannelDonationViewModel()
@StateObject private var mypageViewModel = MyPageViewModel()
@AppStorage("token") private var token: String = UserDefaults.string(forKey: UserDefaultsKey.token)
@AppStorage("auth") private var auth: Bool = UserDefaults.bool(forKey: UserDefaultsKey.auth)
@Environment(\.dismiss) private var dismiss
@State private var tabBarMinY: CGFloat = .greatestFiniteMagnitude
@State private var isShowChannelDonationDialog = false
@State private var isShowAuthView = false
@State private var isShowAuthConfirmView = false
@State private var pendingAction: (() -> Void)? = nil
@State private var payload = Payload()
private let titleBarHeight: CGFloat = 56
private let tabBarHeight: CGFloat = 52
@@ -68,6 +77,10 @@ struct CreatorChannelView: View {
LoadingView()
}
if isShowAuthConfirmView {
authConfirmDialog
}
if isShowChannelDonationDialog {
LiveRoomDonationDialogView(
isShowing: $isShowChannelDonationDialog,
@@ -92,7 +105,11 @@ struct CreatorChannelView: View {
}
}
.navigationBarBackButtonHidden(true)
.fullScreenCover(isPresented: $isShowAuthView) {
authView
}
.onAppear {
configurePayload()
if viewModel.hasLoaded == false {
viewModel.fetchHome(creatorId: creatorId)
}
@@ -129,7 +146,7 @@ struct CreatorChannelView: View {
@ViewBuilder
private var headerSection: some View {
if let creator = viewModel.response?.creator {
CreatorChannelHeaderSection(creator: creator)
CreatorChannelHeaderSection(creator: creator, onTapTalk: handleTalkTap)
}
}
@@ -168,6 +185,57 @@ struct CreatorChannelView: View {
}
}
private var authConfirmDialog: some View {
SodaDialog(
title: I18n.Chat.Auth.dialogTitle,
desc: I18n.Chat.Auth.dialogDescription,
confirmButtonTitle: I18n.Chat.Auth.goToVerification,
confirmButtonAction: {
isShowAuthConfirmView = false
isShowAuthView = true
},
cancelButtonTitle: I18n.Common.cancel,
cancelButtonAction: {
isShowAuthConfirmView = false
pendingAction = nil
},
textAlignment: .center
)
}
private var authView: some View {
BootpayUI(payload: payload, requestType: BootpayRequest.TYPE_AUTHENTICATION)
.onConfirm { _ in true }
.onCancel { _ in isShowAuthView = false }
.onError { _ in
AppState.shared.errorMessage = I18n.Chat.Auth.authenticationError
AppState.shared.isShowErrorPopup = true
isShowAuthView = false
}
.onDone {
DEBUG_LOG("onDone: \($0)")
mypageViewModel.authVerify($0) {
auth = true
isShowAuthView = false
if let action = pendingAction {
pendingAction = nil
action()
}
}
}
.onClose { isShowAuthView = false }
}
private func configurePayload() {
payload.applicationId = BOOTPAY_APP_ID
payload.price = 0
payload.pg = "다날"
payload.method = "본인인증"
payload.orderName = "본인인증"
payload.authenticationId = "\(UserDefaults.string(forKey: .nickname))__\(String(NSTimeIntervalSince1970))"
}
private func selectTab(_ tab: CreatorChannelTab) {
switch tab {
case .audio:
@@ -228,6 +296,43 @@ struct CreatorChannelView: View {
}
}
private func handleTalkTap() {
guard let characterId = viewModel.response?.creator.characterId, characterId > 0 else { return }
let trimmed = token.trimmingCharacters(in: .whitespacesAndNewlines)
guard !trimmed.isEmpty else {
AppState.shared.setAppStep(step: .login)
return
}
let normalizedCountryCode = UserDefaults
.string(forKey: .countryCode)
.trimmingCharacters(in: .whitespacesAndNewlines)
.uppercased()
let isKoreanCountry = normalizedCountryCode.isEmpty || normalizedCountryCode == "KR"
if isKoreanCountry && auth == false {
pendingAction = {
AppState.shared.setAppStep(step: .characterDetail(characterId: characterId))
}
isShowAuthConfirmView = true
return
}
if !UserDefaults.isAdultContentVisible() {
pendingAction = nil
moveToContentSettingsWithGuideToast()
return
}
AppState.shared.setAppStep(step: .characterDetail(characterId: characterId))
}
private func moveToContentSettingsWithGuideToast() {
AppState.shared.setPendingContentSettingsGuideMessage(I18n.Settings.adultContentEnableGuide)
AppState.shared.setAppStep(step: .contentViewSettings)
}
private func showDonationDialog() {
guard let creatorId = viewModel.response?.creator.creatorId else { return }
channelDonationViewModel.setCreatorId(creatorId, shouldFetch: false)