108 lines
4.0 KiB
Swift
108 lines
4.0 KiB
Swift
import SwiftUI
|
||
|
||
struct ContentView: View {
|
||
@EnvironmentObject var appState: AppState
|
||
@State private var showMenu = false
|
||
@State private var isLoading = true // состояние загрузки
|
||
|
||
var body: some View {
|
||
NavigationStack {
|
||
ZStack {
|
||
// Основной контент
|
||
VStack(spacing: 10) {
|
||
HStack(spacing: 10) {
|
||
RouteView()
|
||
WeatherView()
|
||
}
|
||
|
||
SightView()
|
||
}
|
||
.padding()
|
||
.blur(radius: isLoading ? 5 : 0) // слегка размываем, пока загрузка
|
||
.disabled(isLoading) // блокируем взаимодействие с контентом при загрузке
|
||
|
||
// Плавающая кнопка
|
||
VStack {
|
||
Spacer()
|
||
HStack {
|
||
Spacer()
|
||
Button(action: {
|
||
withAnimation(.spring()) {
|
||
showMenu.toggle()
|
||
}
|
||
}) {
|
||
Image("open_menu_icon")
|
||
.resizable()
|
||
.aspectRatio(contentMode: .fit)
|
||
.frame(width: 24, height: 24)
|
||
.padding(10)
|
||
.background(Color(hex: 0x806C59))
|
||
.clipShape(Circle())
|
||
.shadow(radius: 5)
|
||
}
|
||
.padding(.trailing, 20)
|
||
.padding(.bottom, -20)
|
||
}
|
||
}
|
||
|
||
// BottomMenu
|
||
if showMenu {
|
||
BottomMenu(isPresented: $showMenu)
|
||
.transition(.move(edge: .bottom))
|
||
.animation(.spring(response: 0.35, dampingFraction: 0.9), value: showMenu)
|
||
}
|
||
|
||
// Экран загрузки
|
||
if isLoading {
|
||
ZStack {
|
||
Color(hex: 0x806C59)
|
||
.edgesIgnoringSafeArea(.all)
|
||
ProgressView()
|
||
.progressViewStyle(CircularProgressViewStyle(tint: .white))
|
||
.scaleEffect(1.5)
|
||
VStack {
|
||
Spacer()
|
||
HStack {
|
||
Spacer()
|
||
Image("waiting_screen_logo")
|
||
.resizable()
|
||
.scaledToFit()
|
||
.frame(width: 200)
|
||
.padding(20)
|
||
}
|
||
}
|
||
}
|
||
.transition(.opacity)
|
||
.zIndex(1)
|
||
}
|
||
}
|
||
}
|
||
.task {
|
||
await fetchRoutes()
|
||
// Убираем экран загрузки через 2 секунды
|
||
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
|
||
withAnimation(.easeOut(duration: 0.5)) {
|
||
isLoading = false
|
||
}
|
||
}
|
||
}
|
||
.preferredColorScheme(.light)
|
||
}
|
||
|
||
private func fetchRoutes() async {
|
||
guard let url = URL(string: "https://white-nights.krbl.ru/services/content/route") else { return }
|
||
|
||
do {
|
||
let (data, _) = try await URLSession.shared.data(from: url)
|
||
let routes = try JSONDecoder().decode([Route].self, from: data)
|
||
|
||
appState.allRoutes = routes
|
||
if let firstRoute = routes.first {
|
||
appState.selectedRoute = firstRoute
|
||
}
|
||
} catch {
|
||
print("Ошибка загрузки маршрутов: \(error)")
|
||
}
|
||
}
|
||
}
|