289 lines
10 KiB
Swift
289 lines
10 KiB
Swift
//
|
|
// MyPageViewModel.swift
|
|
// SodaLive
|
|
//
|
|
// Created by klaus on 2023/08/10.
|
|
//
|
|
|
|
import Foundation
|
|
import Combine
|
|
|
|
final class MyPageViewModel: ObservableObject {
|
|
|
|
private let repository = UserRepository()
|
|
private let authRepository = AuthRepository()
|
|
private let noticeRepository = NoticeRepository()
|
|
private var subscription = Set<AnyCancellable>()
|
|
private var pendingAuthReceiptId: String?
|
|
private var pendingAuthRequest: AuthVerifyRequest?
|
|
private var pendingAuthSuccess: (() -> Void)?
|
|
|
|
@Published var latestNotice: NoticeItem? = nil
|
|
|
|
@Published var nickname: String = ""
|
|
@Published var profileUrl: String = ""
|
|
@Published var chargeCan: Int = 0
|
|
@Published var rewardCan: Int = 0
|
|
@Published var point: Int = 0
|
|
@Published var isAuth: Bool = false
|
|
|
|
@Published var errorMessage = ""
|
|
@Published var isShowPopup = false
|
|
@Published var isLoading = false
|
|
@Published var isShowAuthView = false
|
|
@Published var isShowAuthContentSettings = false
|
|
@Published var authIsAdultContentVisible = true {
|
|
didSet {
|
|
if !authIsAdultContentVisible {
|
|
authContentType = .ALL
|
|
}
|
|
}
|
|
}
|
|
@Published var authContentType: ContentType = .ALL
|
|
@Published private(set) var isSubmittingAuth = false
|
|
|
|
func getMypage() {
|
|
isLoading = true
|
|
|
|
repository.getMypage()
|
|
.sink { result in
|
|
switch result {
|
|
case .finished:
|
|
DEBUG_LOG("finish")
|
|
case .failure(let error):
|
|
ERROR_LOG(error.localizedDescription)
|
|
}
|
|
} receiveValue: {[unowned self] response in
|
|
self.isLoading = false
|
|
let responseData = response.data
|
|
|
|
do {
|
|
let jsonDecoder = JSONDecoder()
|
|
let decoded = try jsonDecoder.decode(ApiResponse<MyPageResponse>.self, from: responseData)
|
|
|
|
if let data = decoded.data, decoded.success {
|
|
self.nickname = data.nickname
|
|
self.profileUrl = data.profileUrl
|
|
self.chargeCan = data.chargeCan
|
|
self.rewardCan = data.rewardCan
|
|
self.point = data.point
|
|
self.isAuth = data.isAuth
|
|
} else {
|
|
if let message = decoded.message {
|
|
self.errorMessage = message
|
|
} else {
|
|
self.errorMessage = I18n.Common.commonError
|
|
}
|
|
|
|
self.isShowPopup = true
|
|
}
|
|
} catch {
|
|
self.errorMessage = I18n.Common.commonError
|
|
self.isShowPopup = true
|
|
}
|
|
}
|
|
.store(in: &subscription)
|
|
}
|
|
|
|
func authVerify(_ data: [String: Any], onSuccess: (() -> Void)? = nil) {
|
|
guard Thread.isMainThread else {
|
|
DispatchQueue.main.async { [weak self] in
|
|
self?.authVerify(data, onSuccess: onSuccess)
|
|
}
|
|
return
|
|
}
|
|
guard pendingAuthReceiptId == nil, !isSubmittingAuth else { return }
|
|
|
|
guard let payload = data["data"] as? [String: Any],
|
|
let receiptId = payload["receipt_id"] as? String,
|
|
!receiptId.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else {
|
|
errorMessage = I18n.Main.Auth.authenticationError
|
|
isShowPopup = true
|
|
return
|
|
}
|
|
|
|
pendingAuthReceiptId = receiptId
|
|
pendingAuthSuccess = onSuccess
|
|
authIsAdultContentVisible = true
|
|
authContentType = .ALL
|
|
}
|
|
|
|
func presentAuthContentSettings() {
|
|
guard Thread.isMainThread else {
|
|
DispatchQueue.main.async { [weak self] in
|
|
self?.presentAuthContentSettings()
|
|
}
|
|
return
|
|
}
|
|
guard pendingAuthReceiptId != nil, !isSubmittingAuth else { return }
|
|
isShowAuthContentSettings = true
|
|
}
|
|
|
|
func cancelAuthContentSettings() {
|
|
guard Thread.isMainThread else {
|
|
DispatchQueue.main.async { [weak self] in
|
|
self?.cancelAuthContentSettings()
|
|
}
|
|
return
|
|
}
|
|
guard !isSubmittingAuth, isShowAuthContentSettings else { return }
|
|
|
|
clearPendingAuthVerification()
|
|
isShowPopup = false
|
|
}
|
|
|
|
func confirmAuthContentSettings() {
|
|
guard Thread.isMainThread else {
|
|
DispatchQueue.main.async { [weak self] in
|
|
self?.confirmAuthContentSettings()
|
|
}
|
|
return
|
|
}
|
|
guard let receiptId = pendingAuthReceiptId, !isSubmittingAuth else { return }
|
|
|
|
pendingAuthRequest = AuthVerifyRequest(
|
|
receiptId: receiptId,
|
|
isAdultContentVisible: authIsAdultContentVisible,
|
|
contentType: authIsAdultContentVisible ? authContentType : .ALL
|
|
)
|
|
isSubmittingAuth = true
|
|
isShowAuthContentSettings = false
|
|
}
|
|
|
|
func submitPendingAuthVerification() {
|
|
guard Thread.isMainThread else {
|
|
DispatchQueue.main.async { [weak self] in
|
|
self?.submitPendingAuthVerification()
|
|
}
|
|
return
|
|
}
|
|
guard isSubmittingAuth, let request = pendingAuthRequest else { return }
|
|
pendingAuthRequest = nil
|
|
|
|
authRepository.authCertificate(request: request)
|
|
.receive(on: DispatchQueue.main)
|
|
.sink { [weak self] result in
|
|
if case .failure = result {
|
|
self?.handleAuthSubmissionFailure()
|
|
}
|
|
} receiveValue: { [weak self] response in
|
|
guard let self = self else { return }
|
|
|
|
guard (200..<300).contains(response.statusCode) else {
|
|
self.handleAuthSubmissionFailure()
|
|
return
|
|
}
|
|
|
|
do {
|
|
let decoded = try JSONDecoder().decode(ApiResponse<AuthResponse>.self, from: response.data)
|
|
guard decoded.success, decoded.data != nil else {
|
|
self.handleAuthSubmissionFailure()
|
|
return
|
|
}
|
|
|
|
if self.pendingAuthSuccess != nil {
|
|
self.synchronizeAuthenticatedMember()
|
|
} else {
|
|
UserDefaults.set(request.isAdultContentVisible, forKey: .isAdultContentVisible)
|
|
UserDefaults.set(request.contentType.rawValue, forKey: .contentPreference)
|
|
self.restartAfterAuthVerification()
|
|
}
|
|
} catch {
|
|
self.handleAuthSubmissionFailure()
|
|
}
|
|
}
|
|
.store(in: &subscription)
|
|
}
|
|
|
|
private func handleAuthSubmissionFailure() {
|
|
pendingAuthRequest = nil
|
|
isSubmittingAuth = false
|
|
errorMessage = I18n.MyPage.Auth.verificationErrorWithSupport
|
|
isShowPopup = true
|
|
isShowAuthContentSettings = true
|
|
}
|
|
|
|
private func synchronizeAuthenticatedMember() {
|
|
repository.getMemberInfo()
|
|
.receive(on: DispatchQueue.main)
|
|
.sink { [weak self] result in
|
|
if case .failure = result {
|
|
self?.restartAfterAuthVerification()
|
|
}
|
|
} receiveValue: { [weak self] response in
|
|
guard let self = self else { return }
|
|
|
|
guard (200..<300).contains(response.statusCode) else {
|
|
self.restartAfterAuthVerification()
|
|
return
|
|
}
|
|
|
|
do {
|
|
let decoded = try JSONDecoder().decode(ApiResponse<GetMemberInfoResponse>.self, from: response.data)
|
|
guard let data = decoded.data, decoded.success, data.isAuth else {
|
|
self.restartAfterAuthVerification()
|
|
return
|
|
}
|
|
|
|
UserDefaults.set(data.can, forKey: .can)
|
|
UserDefaults.set(data.point, forKey: .point)
|
|
UserDefaults.set(data.isAuth, forKey: .auth)
|
|
UserDefaults.set(data.role.rawValue, forKey: .role)
|
|
UserDefaults.set(data.auditionNotice ?? false, forKey: .isAuditionNotification)
|
|
UserDefaults.set(data.countryCode, forKey: .countryCode)
|
|
UserDefaults.set(data.isAdultContentVisible, forKey: .isAdultContentVisible)
|
|
UserDefaults.set(data.isAdultContentVisible ? data.contentType : ContentType.ALL.rawValue, forKey: .contentPreference)
|
|
self.isAuth = data.isAuth
|
|
|
|
let onSuccess = self.pendingAuthSuccess
|
|
self.clearPendingAuthVerification()
|
|
onSuccess?()
|
|
} catch {
|
|
self.restartAfterAuthVerification()
|
|
}
|
|
}
|
|
.store(in: &subscription)
|
|
}
|
|
|
|
private func clearPendingAuthVerification() {
|
|
pendingAuthReceiptId = nil
|
|
pendingAuthRequest = nil
|
|
pendingAuthSuccess = nil
|
|
isSubmittingAuth = false
|
|
isShowAuthContentSettings = false
|
|
}
|
|
|
|
private func restartAfterAuthVerification() {
|
|
clearPendingAuthVerification()
|
|
AppState.shared.isRestartApp = true
|
|
AppState.shared.setAppStep(step: .splash)
|
|
}
|
|
|
|
func getLatestNotice() {
|
|
noticeRepository.getLatestNotice()
|
|
.sink { result in
|
|
switch result {
|
|
case .finished:
|
|
DEBUG_LOG("finish")
|
|
case .failure(let error):
|
|
ERROR_LOG(error.localizedDescription)
|
|
}
|
|
} receiveValue: {[unowned self] response in
|
|
self.isLoading = false
|
|
let responseData = response.data
|
|
|
|
do {
|
|
let jsonDecoder = JSONDecoder()
|
|
let decoded = try jsonDecoder.decode(ApiResponse<NoticeItem>.self, from: responseData)
|
|
|
|
if let data = decoded.data, decoded.success {
|
|
self.latestNotice = data
|
|
}
|
|
} catch {
|
|
ERROR_LOG(error.localizedDescription)
|
|
}
|
|
}
|
|
.store(in: &subscription)
|
|
}
|
|
}
|