// // AppState.swift // SodaLive // // Created by klaus on 2023/08/09. // import Foundation struct AppRoute: Hashable { let id = UUID() } class AppState: ObservableObject { static let shared = AppState() private var routeStepMap: [AppRoute: AppStep] = [:] @Published var alreadyUpdatedMarketingInfo = false @Published private(set) var appStep: AppStep = .splash @Published private(set) var rootStep: AppStep = .splash @Published var navigationPath: [AppRoute] = [] { didSet { syncStepWithNavigationPath() } } @Published var isShowPlayer = false { didSet { if isShowPlayer { ContentPlayManager.shared.stopAudio() ContentPlayerPlayManager.shared.resetPlayer() } } } @Published var isShowNotificationSettingsDialog = false @Published var pushRoomId = 0 @Published var pushChannelId = 0 @Published var pushMessageId = 0 @Published var pushAudioContentId = 0 @Published var pushSeriesId = 0 @Published var roomId = 0 { didSet { if roomId <= 0 { isShowPlayer = false } } } @Published var eventPopup: EventItem? = nil @Published var purchasedContentId = 0 @Published var purchasedContentOrderType = OrderType.KEEP @Published var isRestartApp = false @Published var startTab: HomeViewModel.CurrentTab = .home @Published var marketingUtmSource = "" @Published var marketingUtmMedium = "" @Published var marketingUtmCampaign = "" @Published var isShowErrorPopup = false @Published var errorMessage = "" private func syncStepWithNavigationPath() { let validRoutes = Set(navigationPath) routeStepMap = routeStepMap.filter { validRoutes.contains($0.key) } if let route = navigationPath.last, let step = routeStepMap[route] { appStep = step } else { appStep = rootStep } } func appStep(for route: AppRoute) -> AppStep? { routeStepMap[route] } func setAppStep(step: AppStep) { DispatchQueue.main.async { switch step { case .splash, .main: self.rootStep = step self.routeStepMap.removeAll() self.navigationPath.removeAll() self.appStep = step default: let route = AppRoute() self.routeStepMap[route] = step self.navigationPath.append(route) self.appStep = step } } } func back() { DispatchQueue.main.async { if self.navigationPath.isEmpty { self.rootStep = .main self.appStep = .main return } _ = self.navigationPath.popLast() } } // 언어 적용 직후 앱을 소프트 재시작(스플래시 -> 메인)하여 전역 UI를 새로고침 func softRestart() { isRestartApp = true setAppStep(step: .splash) DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { self.setAppStep(step: .main) } } }