import SwiftUI struct SplashScreenView: View { @State private var dataService = ChurchDataService.shared @State private var isActive = false @State private var size = 0.8 @State private var opacity = 0.5 @State private var bibleVerse = "" @State private var bibleReference = "" // Timing constants private let fadeInDuration: Double = 0.5 private let baseDisplayDuration: Double = 1.0 private let timePerWord: Double = 0.15 private let minDisplayDuration: Double = 1.5 private let maxDisplayDuration: Double = 3.0 private func calculateDisplayDuration(for text: String) -> Double { let words = text.components(separatedBy: .whitespacesAndNewlines).filter { !$0.isEmpty } let calculatedDuration = baseDisplayDuration + (Double(words.count) * timePerWord) return min(max(calculatedDuration, minDisplayDuration), maxDisplayDuration) } var body: some View { if isActive { MainAppView() } else { ZStack { // Modern background matching the app theme LinearGradient( colors: [.blue.opacity(0.1), .indigo.opacity(0.05)], startPoint: .topLeading, endPoint: .bottomTrailing ) .ignoresSafeArea() // Background pattern for subtle texture GeometryReader { geometry in ForEach(0..<20, id: \.self) { _ in Circle() .fill(.white.opacity(0.02)) .frame(width: 20, height: 20) .position( x: CGFloat.random(in: 0...geometry.size.width), y: CGFloat.random(in: 0...geometry.size.height) ) } } VStack(spacing: 20) { Spacer() // Logo and church info card VStack(spacing: 24) { // Logo with modern background ZStack { Circle() .fill(.regularMaterial) .frame(width: 120, height: 120) .shadow(color: .black.opacity(0.1), radius: 8, x: 0, y: 4) Image("sdalogo") .resizable() .scaledToFit() .frame(width: 80, height: 80) } VStack(spacing: 12) { Text("Rockville-Tolland") .font(.custom("Montserrat-SemiBold", size: 28)) .foregroundStyle(.primary) Text("SDA Church") .font(.custom("Montserrat-Regular", size: 20)) .foregroundStyle(.secondary) // Modern separator Capsule() .fill(Color(hex: "fb8b23")) .frame(width: 80, height: 3) } } Spacer() .frame(maxHeight: 40) // Bible verse card if !bibleVerse.isEmpty { VStack(spacing: 16) { // Quote icon Image(systemName: "quote.opening") .font(.title2) .foregroundStyle(Color(hex: "fb8b23").opacity(0.8)) VStack(spacing: 12) { Text(bibleVerse) .font(.custom("Lora-Italic", size: 18)) .foregroundStyle(.primary) .multilineTextAlignment(.center) .lineSpacing(6) Text(bibleReference) .font(.custom("Montserrat-Regular", size: 14)) .foregroundStyle(Color(hex: "fb8b23")) .fontWeight(.medium) } } .padding(24) .background(.regularMaterial, in: RoundedRectangle(cornerRadius: 20)) .shadow(color: .black.opacity(0.1), radius: 12, x: 0, y: 6) .padding(.horizontal, 20) } Spacer() } .padding() .scaleEffect(size) .opacity(opacity) .task { // Load a random Bible verse from the Rust crate await dataService.loadDailyVerse() if let verse = dataService.dailyVerse { bibleVerse = verse.text bibleReference = verse.reference } else { // Fallback to a default verse if API fails bibleVerse = "For God so loved the world that he gave his one and only Son, that whoever believes in him shall not perish but have eternal life." bibleReference = "John 3:16" } // Calculate display duration based on verse length let displayDuration = calculateDisplayDuration(for: bibleVerse) // Start fade in animation after verse is loaded withAnimation(.easeIn(duration: fadeInDuration)) { self.size = 0.9 self.opacity = 1.0 } // Wait for fade in + calculated display duration before transitioning DispatchQueue.main.asyncAfter(deadline: .now() + fadeInDuration + displayDuration) { withAnimation { self.isActive = true } } } } } } } // Color extension is already defined in FeedItemCard.swift #Preview { SplashScreenView() }