import SwiftUI enum HermesAppMode: String { case demo case live } struct RootView: View { @StateObject private var localization = LocalizationStore() @EnvironmentObject private var analytics: HermesAnalyticsClient @EnvironmentObject private var repository: HermesRepository let mode: HermesAppMode let onModeSelected: (HermesAppMode) -> Void let onStartSession: (String, HermesAppMode) -> Void var body: some View { ZStack(alignment: .top) { HermesTheme.background .ignoresSafeArea() RoundView(onRetry: { onStartSession(localization.localeCode, mode) }) .ignoresSafeArea() topChrome } .environmentObject(localization) .onAppear { analytics.track("app_opened", attributes: ["screen_name": "round", "mode": mode.rawValue]) analytics.track("screen_viewed", attributes: ["screen_name": "round", "mode": mode.rawValue]) } .task(id: "\(localization.localeCode)-\(mode.rawValue)") { onStartSession(localization.localeCode, mode) } .task { while !Task.isCancelled { try? await Task.sleep(nanoseconds: 5_000_000_000) await analytics.flush(using: repository) } } } private var topChrome: some View { HStack(alignment: .top, spacing: 12) { VStack(alignment: .leading, spacing: 6) { Text(localization.string(for: "app.name")) .font(.headline.weight(.bold)) .foregroundStyle(HermesTheme.textPrimary) Text(mode == .demo ? localization.string(for: "mode.demo" ) : localization.string(for: "mode.live")) .font(.caption.weight(.semibold)) .foregroundStyle(HermesTheme.textSecondary) } Spacer(minLength: 12) VStack(alignment: .trailing, spacing: 10) { modeToggle localeToggle } } .padding(.horizontal, HermesTheme.screenPadding) .padding(.top, 16) } private var modeToggle: some View { HStack(spacing: 8) { modeButton(title: localization.string(for: "mode.demo"), appMode: .demo) modeButton(title: localization.string(for: "mode.live"), appMode: .live) } } private var localeToggle: some View { HStack(spacing: 8) { localeButton(title: localization.localeName(for: "en"), localeCode: "en") localeButton(title: localization.localeName(for: "sv"), localeCode: "sv") } } private func modeButton(title: String, appMode: HermesAppMode) -> some View { let isSelected = mode == appMode return Button { onModeSelected(appMode) analytics.track("mode_changed", attributes: ["mode": appMode.rawValue]) } label: { Text(title) .font(.caption.weight(.bold)) .padding(.horizontal, 12) .padding(.vertical, 8) .foregroundStyle(isSelected ? HermesTheme.background : HermesTheme.textPrimary) .background(isSelected ? HermesTheme.accent : HermesTheme.surfaceElevated.opacity(0.9)) .clipShape(Capsule()) } } private func localeButton(title: String, localeCode: String) -> some View { let isSelected = localization.localeCode == localeCode return Button { localization.setLocale(localeCode) analytics.track("locale_changed", attributes: ["locale_code": localeCode]) } label: { Text(title) .font(.caption.weight(.bold)) .padding(.horizontal, 12) .padding(.vertical, 8) .foregroundStyle(isSelected ? HermesTheme.background : HermesTheme.textPrimary) .background(isSelected ? HermesTheme.accent : HermesTheme.surfaceElevated.opacity(0.9)) .clipShape(Capsule()) } } }