feat: Resolving concurrency warnings
This commit is contained in:
@@ -2,6 +2,10 @@
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let settings: [SwiftSetting] = [
|
||||
.enableExperimentalFeature("StrictConcurrency")
|
||||
]
|
||||
|
||||
let package = Package(
|
||||
name: "swift-estimated-pressures-core",
|
||||
platforms: [
|
||||
@@ -100,7 +104,3 @@ let package = Package(
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
let settings: [SwiftSetting] = [
|
||||
.enableExperimentalFeature("StrictConcurrency")
|
||||
]
|
||||
|
||||
@@ -26,6 +26,7 @@ public struct FlaggedEquipmentMeasurementView: View {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
public protocol FlaggedEquipmentMeasurementStyle {
|
||||
associatedtype Body: View
|
||||
typealias Configuration = FlaggedEquipmentMeasurementStyleConfiguration
|
||||
@@ -39,6 +40,8 @@ public struct FlaggedEquipmentMeasurementStyleConfiguration {
|
||||
public let ignoreIfZero: [EquipmentMeasurement.FlaggedMeasurement.FieldKey]
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@preconcurrency
|
||||
public struct AnyFlaggedEquipmentMeasurementStyle: FlaggedEquipmentMeasurementStyle {
|
||||
private var _makeBody: (Configuration) -> AnyView
|
||||
|
||||
@@ -46,6 +49,7 @@ public struct AnyFlaggedEquipmentMeasurementStyle: FlaggedEquipmentMeasurementSt
|
||||
self._makeBody = makeBody
|
||||
}
|
||||
|
||||
@MainActor
|
||||
public init<S: FlaggedEquipmentMeasurementStyle>(_ style: S) {
|
||||
self.init { configuration in
|
||||
AnyView(style.makeBody(configuration: configuration))
|
||||
@@ -57,6 +61,7 @@ public struct AnyFlaggedEquipmentMeasurementStyle: FlaggedEquipmentMeasurementSt
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
public struct GridFlaggedEquipmentMeasurementStyle: FlaggedEquipmentMeasurementStyle {
|
||||
|
||||
public func makeBody(configuration: Configuration) -> some View {
|
||||
@@ -82,15 +87,13 @@ extension FlaggedEquipmentMeasurementStyle where Self == GridFlaggedEquipmentMea
|
||||
public static var grid: Self { .init() }
|
||||
}
|
||||
|
||||
private struct FlaggedEquipmentMeasurementStyleKey: EnvironmentKey {
|
||||
static let defaultValue = AnyFlaggedEquipmentMeasurementStyle(GridFlaggedEquipmentMeasurementStyle())
|
||||
}
|
||||
//fileprivate struct FlaggedEquipmentMeasurementStyleKey: @preconcurrency EnvironmentKey {
|
||||
//
|
||||
// static let defaultValue = AnyFlaggedEquipmentMeasurementStyle(.grid)
|
||||
//}
|
||||
|
||||
extension EnvironmentValues {
|
||||
public var flaggedEquipmentMeasurementStyle: AnyFlaggedEquipmentMeasurementStyle {
|
||||
get { self[FlaggedEquipmentMeasurementStyleKey.self] }
|
||||
set { self[FlaggedEquipmentMeasurementStyleKey.self] = newValue }
|
||||
}
|
||||
@Entry var flaggedEquipmentMeasurementStyle = AnyFlaggedEquipmentMeasurementStyle(.grid)
|
||||
}
|
||||
|
||||
extension View {
|
||||
|
||||
@@ -23,7 +23,7 @@ public struct FlaggedMessageLabel: View {
|
||||
}
|
||||
|
||||
private struct FlaggedMessageLabelStyleKey: EnvironmentKey {
|
||||
static var defaultValue = AnyTextLabelStyle(style: .font(.caption))
|
||||
static let defaultValue = AnyTextLabelStyle(style: .font(.caption))
|
||||
}
|
||||
|
||||
extension EnvironmentValues {
|
||||
|
||||
@@ -27,6 +27,8 @@ extension FlaggedMessageView {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
@preconcurrency
|
||||
public protocol FlaggedMessageViewStyle {
|
||||
associatedtype Body: View
|
||||
typealias Configuration = FlaggedMessageViewStyleConfiguration
|
||||
@@ -117,8 +119,10 @@ extension FlaggedMessageViewStyle where Self == AutomaticFlaggedMessageViewStyle
|
||||
}
|
||||
}
|
||||
|
||||
private struct FlaggedMessageViewStyleKey: EnvironmentKey {
|
||||
static var defaultValue = AnyFlaggedMessageViewStyle(
|
||||
@MainActor
|
||||
private struct FlaggedMessageViewStyleKey: @preconcurrency EnvironmentKey {
|
||||
|
||||
static let defaultValue = AnyFlaggedMessageViewStyle(
|
||||
AutomaticFlaggedMessageViewStyle(horizontalSizeClass: nil)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -23,22 +23,24 @@ public struct FlaggedStatusLabel: View {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public protocol FlaggedStatusLabelStyle {
|
||||
@MainActor
|
||||
@preconcurrency
|
||||
public protocol FlaggedStatusLabelStyle: Sendable {
|
||||
associatedtype Body: View
|
||||
typealias Configuration = FlaggedStatusLabelStyleConfiguration
|
||||
|
||||
func makeBody(configuration: Self.Configuration) -> Self.Body
|
||||
}
|
||||
|
||||
public struct FlaggedStatusLabelStyleConfiguration {
|
||||
public struct FlaggedStatusLabelStyleConfiguration : Sendable{
|
||||
public let status: Flagged.CheckResult.Status
|
||||
}
|
||||
|
||||
public struct AnyFlaggedStatusLabelStyle: FlaggedStatusLabelStyle {
|
||||
private let _makeBody: (Configuration) -> AnyView
|
||||
@MainActor
|
||||
public struct AnyFlaggedStatusLabelStyle: FlaggedStatusLabelStyle, Sendable {
|
||||
private let _makeBody: @Sendable (Configuration) -> AnyView
|
||||
|
||||
internal init(makeBody: @escaping (Configuration) -> AnyView) {
|
||||
internal init(makeBody: @escaping @Sendable (Configuration) -> AnyView) {
|
||||
self._makeBody = makeBody
|
||||
}
|
||||
|
||||
@@ -57,7 +59,7 @@ public struct FlaggedStatusTextLabelStyle: FlaggedStatusLabelStyle {
|
||||
|
||||
let textLabelStyle: AnyTextLabelStyle?
|
||||
|
||||
public func makeBody(configuration: Configuration) -> some View {
|
||||
@MainActor public func makeBody(configuration: Configuration) -> some View {
|
||||
TextLabel(configuration.status.title)
|
||||
.textLabelStyle(
|
||||
textLabelStyle
|
||||
@@ -68,8 +70,8 @@ public struct FlaggedStatusTextLabelStyle: FlaggedStatusLabelStyle {
|
||||
}
|
||||
}
|
||||
|
||||
private struct FlaggedStatusLabelStyleKey: EnvironmentKey {
|
||||
static var defaultValue = AnyFlaggedStatusLabelStyle(
|
||||
private struct FlaggedStatusLabelStyleKey: @preconcurrency EnvironmentKey {
|
||||
@MainActor static let defaultValue = AnyFlaggedStatusLabelStyle(
|
||||
FlaggedStatusTextLabelStyle(
|
||||
textLabelStyle: AnyTextLabelStyle(
|
||||
style: .font(.callout, fontWeight: .bold)
|
||||
|
||||
@@ -42,6 +42,7 @@ extension FlaggedView where Label == EmptyView {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
public protocol FlaggedViewStyle {
|
||||
associatedtype Body: View
|
||||
typealias Configuration = FlaggedViewStyleConfiguration
|
||||
@@ -50,6 +51,7 @@ public protocol FlaggedViewStyle {
|
||||
func makeBody(configuration: Self.Configuration) -> Self.Body
|
||||
}
|
||||
|
||||
@MainActor
|
||||
public struct FlaggedViewStyleConfiguration {
|
||||
public let flagged: Flagged
|
||||
public let label: Label
|
||||
@@ -82,6 +84,7 @@ public struct AnyFlaggedViewStyle: FlaggedViewStyle {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
public struct DefaultFlagViewStyle: FlaggedViewStyle {
|
||||
|
||||
let alignment: HorizontalAlignment
|
||||
@@ -202,6 +205,7 @@ extension Flagged {
|
||||
.foregroundStyle(statusColor)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
public var messageView: some View {
|
||||
FlaggedMessageView(flagged: self)
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ public struct EstimationForm {
|
||||
public init() { }
|
||||
|
||||
@ObservableState
|
||||
public struct State: Equatable {
|
||||
public struct State: Equatable, Sendable {
|
||||
public var cfmPerTon: Int
|
||||
public var coolingCapacity: EquipmentMetadata.CoolingCapacity
|
||||
public var filterPressureDrop: Double?
|
||||
|
||||
@@ -7,9 +7,8 @@ import Styleguide
|
||||
import SwiftUI
|
||||
import TCAExtras
|
||||
|
||||
|
||||
@Reducer
|
||||
public struct FlaggedMeasurementsList {
|
||||
public struct FlaggedMeasurementsList: Sendable {
|
||||
|
||||
@Reducer(state: .equatable)
|
||||
public enum Destination {
|
||||
@@ -17,20 +16,18 @@ public struct FlaggedMeasurementsList {
|
||||
}
|
||||
|
||||
@ObservableState
|
||||
@dynamicMemberLookup
|
||||
public struct State: Equatable {
|
||||
|
||||
@Presents public var destination: Destination.State?
|
||||
@Shared var sharedSettings: SharedPressureEstimationSettings
|
||||
public var estimatedMeasurements: IdentifiedArrayOf<FlaggedMeasurementContainer>
|
||||
|
||||
init(
|
||||
public init(
|
||||
destination: Destination.State? = nil,
|
||||
sharedSettings: Shared<SharedPressureEstimationSettings>,
|
||||
estimatedMeasurements: IdentifiedArrayOf<FlaggedMeasurementContainer> = []
|
||||
sharedSettings: Shared<SharedPressureEstimationSettings>
|
||||
) {
|
||||
self.destination = destination
|
||||
self._sharedSettings = sharedSettings
|
||||
self.estimatedMeasurements = estimatedMeasurements
|
||||
}
|
||||
|
||||
var ignoreIfZeroFields: [EquipmentMeasurement.FlaggedMeasurement.FieldKey] {
|
||||
@@ -39,21 +36,9 @@ public struct FlaggedMeasurementsList {
|
||||
return [.coilDrop, .filterDrop]
|
||||
}
|
||||
|
||||
#warning("Move to shared settings.")
|
||||
public struct FlaggedMeasurementContainer: Equatable, Identifiable {
|
||||
public let id: UUID
|
||||
public var flaggedMeasurement: EquipmentMeasurement.FlaggedMeasurement
|
||||
public var name: String
|
||||
|
||||
public init(
|
||||
id: UUID,
|
||||
name: String,
|
||||
flaggedMeasurement: EquipmentMeasurement.FlaggedMeasurement
|
||||
) {
|
||||
self.id = id
|
||||
self.name = name
|
||||
self.flaggedMeasurement = flaggedMeasurement
|
||||
}
|
||||
public subscript<T>(dynamicMember keyPath: WritableKeyPath<SharedPressureEstimationSettings, T>) -> T {
|
||||
get { sharedSettings[keyPath: keyPath] }
|
||||
set { sharedSettings[keyPath: keyPath] = newValue }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +49,7 @@ public struct FlaggedMeasurementsList {
|
||||
case view(View)
|
||||
|
||||
@CasePathable
|
||||
public enum ReceiveAction {
|
||||
public enum ReceiveAction: Sendable {
|
||||
case existingFlaggedMeasurement(EquipmentMeasurement.FlaggedMeasurement)
|
||||
case estimatedFlaggedMeasurement(name: String, measurement: EquipmentMeasurement.FlaggedMeasurement)
|
||||
}
|
||||
@@ -73,7 +58,7 @@ public struct FlaggedMeasurementsList {
|
||||
public enum View {
|
||||
case addButtonTapped
|
||||
case destination(DestinationAction)
|
||||
case editButtonTapped(id: State.FlaggedMeasurementContainer.ID)
|
||||
case editButtonTapped(id: SharedPressureEstimationSettings.FlaggedMeasurementContainer.ID)
|
||||
case onAppear
|
||||
|
||||
@CasePathable
|
||||
@@ -96,7 +81,7 @@ public struct FlaggedMeasurementsList {
|
||||
return .none
|
||||
|
||||
case let .estimatedFlaggedMeasurement(name: name, measurement: measurement):
|
||||
state.estimatedMeasurements.append(
|
||||
state.flaggedEstimations.append(
|
||||
.init(
|
||||
id: uuid(),
|
||||
name: name,
|
||||
@@ -242,7 +227,7 @@ public struct FlaggedMeasurementListView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
ForEach(store.estimatedMeasurements) { measurement in
|
||||
ForEach(store.flaggedEstimations) { measurement in
|
||||
Section {
|
||||
FlaggedEquipmentMeasurementView(
|
||||
measurement.flaggedMeasurement,
|
||||
@@ -295,34 +280,36 @@ public struct FlaggedMeasurementListView: View {
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
private let sharedPressureEstimationSettings = SharedPressureEstimationSettings(
|
||||
budgets: .init(equipmentType: .airHandler, fanType: .constantSpeed),
|
||||
equipmentMeasurement: .mock(type: .airHandler),
|
||||
flaggedEquipmentMeasurement: nil
|
||||
)
|
||||
|
||||
private let flaggedMeasurements = IdentifiedArrayOf<FlaggedMeasurementsList.State.FlaggedMeasurementContainer>(
|
||||
private let budgets = BudgetedPercentEnvelope(equipmentType: .airHandler, fanType: .constantSpeed)
|
||||
private let flaggedMeasurements = IdentifiedArrayOf<SharedPressureEstimationSettings.FlaggedMeasurementContainer>(
|
||||
uniqueElements: [
|
||||
.init(
|
||||
id: UUID(0),
|
||||
name: "Existing",
|
||||
flaggedMeasurement: .init(
|
||||
budgets: sharedPressureEstimationSettings.budgets!,
|
||||
measurement: sharedPressureEstimationSettings.equipmentMeasurement!,
|
||||
ratedPressures: sharedPressureEstimationSettings.equipmentMetadata.ratedStaticPressures,
|
||||
tons: sharedPressureEstimationSettings.equipmentMetadata.coolingCapacity
|
||||
budgets: budgets,
|
||||
measurement: .mock(type: .airHandler),
|
||||
ratedPressures: .init(),
|
||||
tons: .default
|
||||
)
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
#Preview {
|
||||
NavigationStack {
|
||||
FlaggedMeasurementListView(
|
||||
store: Store(
|
||||
initialState: FlaggedMeasurementsList.State(
|
||||
sharedSettings: Shared(sharedPressureEstimationSettings)
|
||||
sharedSettings: Shared(
|
||||
SharedPressureEstimationSettings(
|
||||
budgets: budgets,
|
||||
equipmentMeasurement: .mock(type: .airHandler),
|
||||
flaggedEquipmentMeasurement: nil,
|
||||
flaggedEstimations: flaggedMeasurements
|
||||
)
|
||||
)
|
||||
)
|
||||
) {
|
||||
FlaggedMeasurementsList()
|
||||
@@ -331,18 +318,4 @@ private let flaggedMeasurements = IdentifiedArrayOf<FlaggedMeasurementsList.Stat
|
||||
}
|
||||
}
|
||||
|
||||
#Preview("Landscape", traits: .landscapeLeft) {
|
||||
NavigationStack {
|
||||
FlaggedMeasurementListView(
|
||||
store: Store(
|
||||
initialState: FlaggedMeasurementsList.State(
|
||||
sharedSettings: Shared(sharedPressureEstimationSettings)
|
||||
)
|
||||
) {
|
||||
FlaggedMeasurementsList()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
import ComposableArchitecture
|
||||
import Foundation
|
||||
import SharedModels
|
||||
|
||||
/// Holds onto shared values for several of the views in this feature.
|
||||
@dynamicMemberLookup
|
||||
public struct SharedPressureEstimationSettings: Equatable {
|
||||
public struct SharedPressureEstimationSettings: Equatable, Sendable {
|
||||
public var budgets: BudgetedPercentEnvelope?
|
||||
public var equipmentMeasurement: EquipmentMeasurement?
|
||||
public var equipmentMetadata: EquipmentMetadata
|
||||
public var flaggedEquipmentMeasurement: EquipmentMeasurement.FlaggedMeasurement?
|
||||
public var flaggedEstimations: IdentifiedArrayOf<FlaggedMeasurementContainer>
|
||||
public var heatingCapacity: Double?
|
||||
public var manufacturersIncludedFilterPressureDrop: Double?
|
||||
|
||||
@@ -16,6 +18,7 @@ public struct SharedPressureEstimationSettings: Equatable {
|
||||
equipmentMeasurement: EquipmentMeasurement? = nil,
|
||||
equipmentMetadata: EquipmentMetadata = .init(),
|
||||
flaggedEquipmentMeasurement: EquipmentMeasurement.FlaggedMeasurement? = nil,
|
||||
flaggedEstimations: IdentifiedArrayOf<FlaggedMeasurementContainer> = [],
|
||||
heatingCapacity: Double? = nil,
|
||||
manufacturersIncludedFilterPressureDrop: Double? = nil
|
||||
) {
|
||||
@@ -23,6 +26,7 @@ public struct SharedPressureEstimationSettings: Equatable {
|
||||
self.equipmentMeasurement = equipmentMeasurement
|
||||
self.equipmentMetadata = equipmentMetadata
|
||||
self.flaggedEquipmentMeasurement = flaggedEquipmentMeasurement
|
||||
self.flaggedEstimations = flaggedEstimations
|
||||
self.heatingCapacity = heatingCapacity
|
||||
self.manufacturersIncludedFilterPressureDrop = manufacturersIncludedFilterPressureDrop
|
||||
}
|
||||
@@ -31,6 +35,22 @@ public struct SharedPressureEstimationSettings: Equatable {
|
||||
get { equipmentMetadata[keyPath: keyPath] }
|
||||
set { equipmentMetadata[keyPath: keyPath] = newValue }
|
||||
}
|
||||
|
||||
public struct FlaggedMeasurementContainer: Equatable, Identifiable, Sendable {
|
||||
public let id: UUID
|
||||
public var flaggedMeasurement: EquipmentMeasurement.FlaggedMeasurement
|
||||
public var name: String
|
||||
|
||||
public init(
|
||||
id: UUID,
|
||||
name: String,
|
||||
flaggedMeasurement: EquipmentMeasurement.FlaggedMeasurement
|
||||
) {
|
||||
self.id = id
|
||||
self.name = name
|
||||
self.flaggedMeasurement = flaggedMeasurement
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension PersistenceReaderKey where Self == InMemoryKey<SharedPressureEstimationSettings> {
|
||||
|
||||
@@ -19,7 +19,7 @@ public struct Flagged: Equatable, Sendable {
|
||||
|
||||
public init(
|
||||
wrappedValue: Double,
|
||||
_ checkValue: @escaping (Double) -> CheckResult
|
||||
_ checkValue: @escaping @Sendable (Double) -> CheckResult
|
||||
) {
|
||||
self.checkValue = .init(checkValue)
|
||||
self.wrappedValue = wrappedValue
|
||||
@@ -35,10 +35,10 @@ public struct Flagged: Equatable, Sendable {
|
||||
checkValue(wrappedValue)
|
||||
}
|
||||
|
||||
public struct GoodMessageHandler {
|
||||
let message: (Double) -> String?
|
||||
public struct GoodMessageHandler: Sendable {
|
||||
let message: @Sendable (Double) -> String?
|
||||
|
||||
public init(message: @escaping (Double) -> String?) {
|
||||
public init(message: @escaping @Sendable (Double) -> String?) {
|
||||
self.message = message
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Foundation
|
||||
|
||||
extension Optional: ExpressibleByIntegerLiteral where Wrapped: ExpressibleByIntegerLiteral {
|
||||
extension Optional: @retroactive ExpressibleByIntegerLiteral where Wrapped: ExpressibleByIntegerLiteral {
|
||||
|
||||
public typealias IntegerLiteralType = Wrapped.IntegerLiteralType
|
||||
|
||||
@@ -9,7 +9,7 @@ extension Optional: ExpressibleByIntegerLiteral where Wrapped: ExpressibleByInte
|
||||
}
|
||||
}
|
||||
|
||||
extension Optional: ExpressibleByFloatLiteral where Wrapped: ExpressibleByFloatLiteral {
|
||||
extension Optional: @retroactive ExpressibleByFloatLiteral where Wrapped: ExpressibleByFloatLiteral {
|
||||
public typealias FloatLiteralType = Wrapped.FloatLiteralType
|
||||
|
||||
public init(floatLiteral value: Wrapped.FloatLiteralType) {
|
||||
@@ -17,7 +17,7 @@ extension Optional: ExpressibleByFloatLiteral where Wrapped: ExpressibleByFloatL
|
||||
}
|
||||
}
|
||||
|
||||
extension Optional: AdditiveArithmetic where Wrapped: AdditiveArithmetic {
|
||||
extension Optional: @retroactive AdditiveArithmetic where Wrapped: AdditiveArithmetic {
|
||||
public static func - (lhs: Optional<Wrapped>, rhs: Optional<Wrapped>) -> Optional<Wrapped> {
|
||||
switch (lhs, rhs) {
|
||||
|
||||
@@ -58,7 +58,7 @@ extension Optional: AdditiveArithmetic where Wrapped: AdditiveArithmetic {
|
||||
|
||||
}
|
||||
|
||||
extension Optional: Numeric where Wrapped: Numeric {
|
||||
extension Optional: @retroactive Numeric where Wrapped: Numeric {
|
||||
|
||||
public static func *= (lhs: inout Optional<Wrapped>, rhs: Optional<Wrapped>) {
|
||||
switch (lhs, rhs) {
|
||||
@@ -107,7 +107,7 @@ extension Optional: Numeric where Wrapped: Numeric {
|
||||
public typealias Magnitude = Wrapped.Magnitude
|
||||
}
|
||||
|
||||
extension Optional: Comparable where Wrapped: Comparable {
|
||||
extension Optional: @retroactive Comparable where Wrapped: Comparable {
|
||||
public static func < (lhs: Optional<Wrapped>, rhs: Optional<Wrapped>) -> Bool {
|
||||
switch (lhs, rhs) {
|
||||
case let (.some(lhs), .some(rhs)):
|
||||
|
||||
@@ -72,7 +72,7 @@ extension Percentage: Comparable {
|
||||
|
||||
extension Percentage: CustomStringConvertible {
|
||||
|
||||
static var formatter: NumberFormatter = {
|
||||
static let formatter: NumberFormatter = {
|
||||
let formatter = NumberFormatter()
|
||||
formatter.numberStyle = .percent
|
||||
return formatter
|
||||
|
||||
@@ -2,7 +2,7 @@ import ComposableArchitecture
|
||||
import SwiftUI
|
||||
|
||||
@Reducer
|
||||
public struct InfoViewFeature {
|
||||
public struct InfoViewFeature: Sendable {
|
||||
|
||||
public init() { }
|
||||
|
||||
|
||||
@@ -10,21 +10,23 @@ public enum NextButtonType { }
|
||||
public enum ResetButtonType { }
|
||||
|
||||
/// A type erased button style, used to style buttons in a namespace.
|
||||
public struct AnyButtonStyle<ButtonType>: ButtonStyle {
|
||||
private let _makeBody: (Configuration) -> AnyView
|
||||
|
||||
public init<S: ButtonStyle>(_ style: S) {
|
||||
self._makeBody = { configuration in
|
||||
AnyView(style.makeBody(configuration: configuration))
|
||||
}
|
||||
}
|
||||
|
||||
public func makeBody(configuration: Configuration) -> some View {
|
||||
self._makeBody(configuration)
|
||||
}
|
||||
}
|
||||
//@MainActor
|
||||
//public struct AnyButtonStyle<ButtonType>: ButtonStyle, Sendable {
|
||||
// private let _makeBody: @Sendable (Configuration) -> AnyView
|
||||
//
|
||||
// public init<S: ButtonStyle>(_ style: S) where S: Sendable, S.Body: Sendable {
|
||||
// self._makeBody = { configuration in
|
||||
// AnyView(style.makeBody(configuration: configuration))
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public func makeBody(configuration: Configuration) -> some View {
|
||||
// self._makeBody(configuration)
|
||||
// }
|
||||
//}
|
||||
|
||||
/// A type erased primitive button style, used to style buttons in a namespace.
|
||||
@MainActor
|
||||
public struct AnyPrimitiveButtonStyle<ButtonType>: PrimitiveButtonStyle {
|
||||
private let _makeBody: (Configuration) -> AnyView
|
||||
|
||||
@@ -40,7 +42,8 @@ public struct AnyPrimitiveButtonStyle<ButtonType>: PrimitiveButtonStyle {
|
||||
}
|
||||
|
||||
/// The default info button style.
|
||||
public struct DefaultInfoButtonStyle<Style: LabelStyle>: ButtonStyle {
|
||||
@MainActor
|
||||
public struct DefaultInfoButtonStyle<Style: LabelStyle>: PrimitiveButtonStyle {
|
||||
let color: Color
|
||||
let font: Font
|
||||
let labelStyle: Style
|
||||
@@ -56,11 +59,17 @@ public struct DefaultInfoButtonStyle<Style: LabelStyle>: ButtonStyle {
|
||||
}
|
||||
|
||||
public func makeBody(configuration: Configuration) -> some View {
|
||||
Button(role: configuration.role, action: configuration.trigger) {
|
||||
configuration.label
|
||||
.font(font)
|
||||
.foregroundStyle(color.opacity(configuration.isPressed ? 0.5 : 1))
|
||||
.foregroundStyle(color)
|
||||
.labelStyle(labelStyle)
|
||||
.scaleEffect(configuration.isPressed ? 0.8 : 1)
|
||||
}
|
||||
// configuration.label
|
||||
// .font(font)
|
||||
// .foregroundStyle(color.opacity(configuration.isPressed ? 0.5 : 1))
|
||||
// .labelStyle(labelStyle)
|
||||
// .scaleEffect(configuration.isPressed ? 0.8 : 1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,32 +113,40 @@ extension AnyPrimitiveButtonStyle<NextButtonType> {
|
||||
public static var toolbar: Self { .init(ToolbarNextButtonStyle()) }
|
||||
}
|
||||
|
||||
extension AnyButtonStyle where ButtonType == InfoButtonType {
|
||||
public static var `default`: Self {
|
||||
.init(DefaultInfoButtonStyle<IconOnlyLabelStyle>(labelStyle: .iconOnly))
|
||||
}
|
||||
//extension AnyButtonStyle where ButtonType == InfoButtonType {
|
||||
// public static var `default`: Self {
|
||||
// .init(DefaultInfoButtonStyle<IconOnlyLabelStyle>(labelStyle: .iconOnly))
|
||||
// }
|
||||
//
|
||||
// public static func `default`<S: LabelStyle>(color: Color, font: Font, labelStyle: S) -> Self {
|
||||
// .init(DefaultInfoButtonStyle<S>(color: color, font: font, labelStyle: labelStyle))
|
||||
// }
|
||||
//}
|
||||
|
||||
public static func `default`<S: LabelStyle>(color: Color, font: Font, labelStyle: S) -> Self {
|
||||
.init(DefaultInfoButtonStyle<S>(color: color, font: font, labelStyle: labelStyle))
|
||||
private struct InfoButtonStyleKey: @preconcurrency EnvironmentKey {
|
||||
@MainActor
|
||||
static var defaultValue: AnyPrimitiveButtonStyle<InfoButtonType> {
|
||||
AnyPrimitiveButtonStyle<InfoButtonType>(DefaultInfoButtonStyle(labelStyle: .iconOnly))
|
||||
}
|
||||
}
|
||||
|
||||
private struct InfoButtonStyleKey: EnvironmentKey {
|
||||
static var defaultValue = AnyButtonStyle<InfoButtonType>.default
|
||||
}
|
||||
|
||||
private struct NextButtonStyleKey: EnvironmentKey {
|
||||
static var defaultValue = AnyPrimitiveButtonStyle<NextButtonType>(
|
||||
@MainActor
|
||||
static var defaultValue: AnyPrimitiveButtonStyle<NextButtonType> {
|
||||
AnyPrimitiveButtonStyle<NextButtonType>(
|
||||
DefaultNextButtonStyle<BorderedProminentButtonStyle, NextLabelStyle>()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private struct ResetButtonStyleKey: EnvironmentKey {
|
||||
static var defaultValue = AnyPrimitiveButtonStyle<ResetButtonType>(.borderedProminent)
|
||||
static let defaultValue = AnyPrimitiveButtonStyle<ResetButtonType>(.borderedProminent)
|
||||
}
|
||||
|
||||
extension EnvironmentValues {
|
||||
var infoButtonStyle: AnyButtonStyle<InfoButtonType> {
|
||||
// @Entry var infoButtonStyle: AnyButtonStyle<InfoButtonType> = AnyButtonStyle.default
|
||||
|
||||
var infoButtonStyle: AnyPrimitiveButtonStyle<InfoButtonType> {
|
||||
get { self[InfoButtonStyleKey.self] }
|
||||
set { self[InfoButtonStyleKey.self] = newValue }
|
||||
}
|
||||
@@ -148,13 +165,13 @@ extension EnvironmentValues {
|
||||
extension View {
|
||||
|
||||
/// Sets the button style for the ``InfoButton`` type.
|
||||
public func infoButtonStyle(_ style: AnyButtonStyle<InfoButtonType>) -> some View {
|
||||
public func infoButtonStyle(_ style: AnyPrimitiveButtonStyle<InfoButtonType>) -> some View {
|
||||
environment(\.infoButtonStyle, style)
|
||||
}
|
||||
|
||||
/// Sets the button style for the ``InfoButton`` type.
|
||||
public func infoButtonStyle<S: ButtonStyle>(_ style: S) -> some View {
|
||||
infoButtonStyle(AnyButtonStyle(style))
|
||||
public func infoButtonStyle<S: PrimitiveButtonStyle>(_ style: S) -> some View {
|
||||
infoButtonStyle(AnyPrimitiveButtonStyle(style))
|
||||
}
|
||||
|
||||
/// Sets the button style for the ``NextButton`` type.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import SwiftUI
|
||||
|
||||
@MainActor
|
||||
public protocol TextLabelStyle {
|
||||
|
||||
associatedtype Body: View
|
||||
@@ -28,6 +29,7 @@ public struct TextLabelConfiguration {
|
||||
public let label: TextLabelConfiguration.Label
|
||||
}
|
||||
|
||||
@MainActor
|
||||
public struct AnyTextLabelStyle: TextLabelStyle {
|
||||
private var _makeBody: (Configuration) -> AnyView
|
||||
|
||||
@@ -57,6 +59,7 @@ public struct AnyTextLabelStyle: TextLabelStyle {
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
public struct AutomaticTextLabelStyle: TextLabelStyle {
|
||||
public func makeBody(configuration: Configuration) -> some View {
|
||||
configuration.label
|
||||
|
||||
Reference in New Issue
Block a user