70 lines
2.9 KiB
Swift
70 lines
2.9 KiB
Swift
//
|
|
// OnboardPathEnvironmentKey.swift
|
|
//
|
|
// Copyright 2026 Brendan Szymanski <hello@bscubed.dev>
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
//
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
//
|
|
|
|
import Logging
|
|
import LuminateCore
|
|
import Portico
|
|
|
|
private let logger = Logger(label: "\(AppInfo.identifier).onboarding")
|
|
|
|
/// The environment slot that carries `OnboardWindow`'s navigation path down the onboarding tree.
|
|
///
|
|
/// The slot holds the `Binding` itself, not the path value: Portico's `@Environment` is a read-only
|
|
/// view of a slot, so a consumer can only push by writing through a binding that the injecting
|
|
/// window owns. Onboarding-specific by design -- a future main-window stack gets its own slot
|
|
/// rather than sharing this one.
|
|
package enum OnboardPathEnvironmentKey: EnvironmentKey {
|
|
/// The inert binding used when nothing injected a path.
|
|
///
|
|
/// Reads yield an empty stack and writes are logged and dropped, so a page mounted outside
|
|
/// `OnboardWindow` (a unit test, a preview harness) reports the mistake instead of silently
|
|
/// appearing to navigate.
|
|
package static var defaultValue: Binding<[OnboardDestination]> {
|
|
Binding(
|
|
get: { [] },
|
|
set: { _ in
|
|
logger.error("Dropped an onboarding navigation push: no OnboardWindow injected \\.onboardPath")
|
|
}
|
|
)
|
|
}
|
|
}
|
|
|
|
extension EnvironmentValues {
|
|
/// The onboarding navigation path visible to this subtree.
|
|
///
|
|
/// ```swift
|
|
/// // Injection, once, on OnboardWindow's NavigationView:
|
|
/// NavigationView(path: $onboardPath) { ... }.environment(\.onboardPath, $onboardPath)
|
|
///
|
|
/// // Consumption in any onboarding page:
|
|
/// @Environment(\.onboardPath) private var onboardPath
|
|
/// onboardPath.wrappedValue.append(.manualLogin)
|
|
/// ```
|
|
///
|
|
/// The accessors deliberately route through `self[OnboardPathEnvironmentKey.self]`: Portico
|
|
/// resolves a key path by reading it with a probe installed and capturing the box the subscript
|
|
/// hands over, so a computed property that bypassed the subscript would leave the slot
|
|
/// unresolvable.
|
|
package var onboardPath: Binding<[OnboardDestination]> {
|
|
get { self[OnboardPathEnvironmentKey.self] }
|
|
set { self[OnboardPathEnvironmentKey.self] = newValue }
|
|
}
|
|
}
|