Files
hermes/mobile/ios-app/App/RootView.swift
T

113 lines
4.0 KiB
Swift

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())
}
}
}