Created
June 22, 2024 11:20
-
-
Save swift2geek/4efdf2fba26afa28505fa6d41b271ce2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// RootView.swift | |
// nutritionApp | |
// | |
// | |
// | |
import Combine | |
import Factory | |
import SwiftUI | |
import ToastUI | |
struct RootView: View { | |
@ObservedObject var navigationService: NavigationService | |
@ObservedObject var appViewBuilder: ApplicationViewBuilder | |
@State private var selectedTab: Int = 0 | |
@State private var cancellables = Set<AnyCancellable>() | |
private let userService: UserServiceType = Container.shared.userService() | |
@State private var isLoading = false | |
@State private var showToast = false | |
@State private var toastMessage = "" | |
var authService: any AuthServiceType = Container.shared.authService() | |
var body: some View { | |
ZStack { | |
if navigationService.isOnboardingCompleted { | |
mainTabView | |
.onAppear(perform: { | |
// TODO: - @vv ВЫНЕСТИ ЛОГИКУ в Интерактор | |
if let authToken = authService.getToken() { | |
isLoading = true | |
authService.validateToken(token: authToken) | |
.sink(receiveCompletion: { completion in | |
isLoading = false | |
switch completion { | |
case .finished: | |
print("Token validation completed.") | |
case .failure(let error): | |
print("Token validation failed: \(error.localizedDescription)") | |
toastMessage = "Token validation failed: \(error.localizedDescription)" | |
showToast = true | |
// TODO: - logout user! Rethink how it should be done centralized | |
navigationService.isOnboardingCompleted = false | |
} | |
}, receiveValue: { userDTO in | |
print("Received user: \(userDTO)") | |
let user = User(from: userDTO) | |
self.userService.save(user) | |
}) | |
.store(in: &cancellables) | |
} | |
}) | |
} else { | |
onboardingStack | |
} | |
if isLoading { | |
ProgressView("Loading...") | |
.progressViewStyle(CircularProgressViewStyle()) | |
.frame(maxWidth: .infinity, maxHeight: .infinity) | |
.background(Color.black.opacity(0.5)) | |
} | |
} | |
.toast(isPresented: $showToast, dismissAfter: 2.0) { | |
ToastView(toastMessage) | |
.toastViewStyle(WarningToastViewStyle()) | |
} | |
} | |
var mainTabView: some View { | |
TabView(selection: $selectedTab) { | |
appViewBuilder.build(view: .feed) | |
.tabItem { | |
Image("chat") | |
} | |
.tag(0) | |
appViewBuilder.build(view: .statistics) | |
.tabItem { | |
Image("shift") | |
} | |
.tag(1) | |
NavigationStack(path: Binding(get: { | |
navigationService.items.filter { isProfileRelatedPath($0) } | |
}, set: { filteredPaths in | |
navigationService.items = filteredPaths | |
})) { | |
appViewBuilder.build(view: .profile) | |
.navigationDestination(for: Views.self) { path in | |
appViewBuilder.build(view: path) | |
} | |
} | |
.tabItem { | |
Image("user") | |
} | |
.tag(2) | |
.fullScreenCover(isPresented: .constant($navigationService.modalView.wrappedValue != nil)) { | |
if let modal = navigationService.modalView { | |
appViewBuilder.build(view: modal) | |
} | |
} | |
appViewBuilder.build(view: .settings) | |
.tabItem { | |
Image("settings") | |
} | |
.tag(3) | |
} | |
.accentColor(.main) | |
} | |
var onboardingStack: some View { | |
NavigationStack(path: $navigationService.items) { | |
appViewBuilder.build(view: .main) | |
.navigationDestination(for: Views.self) { path in | |
appViewBuilder.build(view: path) | |
} | |
} | |
.fullScreenCover(isPresented: .constant($navigationService.modalView.wrappedValue != nil)) { | |
if let modal = navigationService.modalView { | |
appViewBuilder.build(view: modal) | |
} | |
} | |
.alert(isPresented: .constant($navigationService.alert.wrappedValue != nil)) { | |
switch navigationService.alert { | |
case .defaultAlert(let yesAction, let noAction): | |
return Alert(title: Text("Title"), | |
primaryButton: .default(Text("Yes"), action: yesAction), | |
secondaryButton: .destructive(Text("No"), action: noAction)) | |
case .none: | |
fatalError("Alert data not found.") | |
} | |
} | |
} | |
// TODO: - @VV crutch to filter out unexpected views in the second naviStack in Profile tab | |
private func isProfileRelatedPath(_ path: Views) -> Bool { | |
switch path { | |
case .profile, .editWeight, .editHeight, .editWeightTarget, .accountPage: | |
return true | |
default: | |
return false | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment