63 lines
2.7 KiB
Swift
63 lines
2.7 KiB
Swift
// ── ChronoMind App Entry Point ─────────────────────────────────
|
|
|
|
import SwiftUI
|
|
import WidgetKit
|
|
|
|
@main
|
|
struct ChronoMindApp: App {
|
|
@StateObject private var timerStore = TimerStore()
|
|
@StateObject private var notificationManager = CMNotificationManager.shared
|
|
@StateObject private var gamification = GamificationStore.shared
|
|
@StateObject private var authService = CMAuthService.shared
|
|
@Environment(\.scenePhase) private var scenePhase
|
|
|
|
var body: some Scene {
|
|
WindowGroup {
|
|
Group {
|
|
if authService.isLoggedIn {
|
|
ZStack {
|
|
ContentView()
|
|
.environmentObject(timerStore)
|
|
.environmentObject(notificationManager)
|
|
.environmentObject(gamification)
|
|
.preferredColorScheme(.dark)
|
|
.task {
|
|
notificationManager.registerCategories()
|
|
await notificationManager.requestPermission()
|
|
}
|
|
.onReceive(NotificationCenter.default.publisher(for: .chronoMindTimersDidChange)) { _ in
|
|
WidgetCenter.shared.reloadAllTimelines()
|
|
}
|
|
|
|
// Badge celebration overlay
|
|
if let badge = gamification.newBadge {
|
|
BadgeCelebrationOverlay(badge: badge) {
|
|
gamification.clearNewBadge()
|
|
}
|
|
.transition(.opacity)
|
|
.zIndex(100)
|
|
}
|
|
}
|
|
.animation(.easeInOut, value: gamification.newBadge != nil)
|
|
} else {
|
|
CMLoginView(authService: authService)
|
|
}
|
|
}
|
|
.onChange(of: scenePhase) { _, newPhase in
|
|
switch newPhase {
|
|
case .active:
|
|
CMTelemetryService.shared.start()
|
|
FeatureFlagService.shared.start(userId: authService.currentUser?.id)
|
|
CMTelemetryService.shared.trackEvent("info", module: "app", name: "app_foregrounded")
|
|
case .background:
|
|
CMTelemetryService.shared.trackEvent("info", module: "app", name: "app_backgrounded")
|
|
CMTelemetryService.shared.flush()
|
|
FeatureFlagService.shared.stop()
|
|
default:
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|