Rebuild the app around recurring screen-time blocking rules modeled on Opal's My Apps tab: - Onboarding with FamilyControls Screen Time authorization - Apps home with Blocked Apps tiles and live rule cards - New Rule sheet: Schedule/Time Limit/Open Limit types + preset gallery - Rule editors: time windows (incl. overnight), day picker, app selection via FamilyActivityPicker (Block/Allow Only), rename, Hold to Commit - Hard Mode: active hard rules cannot be edited, disabled, deleted, or unblocked until their window ends; soft rules pause until next window - Shield enforcement through per-rule ManagedSettingsStore + RuleEnforcer - 73 unit tests (Swift Testing) + 16 UI tests (XCUITest) with launch-arg harness for in-memory storage, mocked authorization, seeded scenarios - docs/RULES_FEATURE_SPEC.md: spec derived from the reference recording Known gap: background window transitions and time/open-limit thresholds need a DeviceActivityMonitor extension; shields currently sync while the app is running. Co-Authored-By: Claude <noreply@anthropic.com>
33 lines
935 B
Swift
33 lines
935 B
Swift
//
|
|
// RootView.swift
|
|
// Severed
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
/// Gates the app on onboarding: until the user has walked through the welcome
|
|
/// and Screen Time permission steps, nothing else is reachable.
|
|
struct RootView: View {
|
|
@AppStorage("hasCompletedOnboarding") private var hasCompletedOnboarding = false
|
|
@Environment(ScreenTimeAuthorization.self) private var authorization
|
|
@Environment(\.scenePhase) private var scenePhase
|
|
|
|
var body: some View {
|
|
Group {
|
|
if hasCompletedOnboarding {
|
|
AppsHomeView()
|
|
} else {
|
|
OnboardingView {
|
|
hasCompletedOnboarding = true
|
|
}
|
|
}
|
|
}
|
|
.onChange(of: scenePhase) { _, phase in
|
|
// Pick up permission changes made in Settings while we were backgrounded.
|
|
if phase == .active {
|
|
authorization.refresh()
|
|
}
|
|
}
|
|
}
|
|
}
|