diff --git a/BuildTools/Package.resolved b/BuildTools/Package.resolved index 5f737098f75..6c6b795f76d 100644 --- a/BuildTools/Package.resolved +++ b/BuildTools/Package.resolved @@ -168,8 +168,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/SimplyDanny/SwiftLintPlugins", "state" : { - "revision" : "7a3d77f3dd9f91d5cea138e52c20cfceabf352de", - "version" : "0.58.2" + "revision" : "8545ddf4de043e6f2051c5cf204f39ef778ebf6b", + "version" : "0.59.1" } }, { diff --git a/Modules/Sources/PointOfSale/Analytics/POSAnalyticsEvent.swift b/Modules/Sources/PointOfSale/Analytics/POSAnalyticsEvent.swift index adfb5f1a384..7331927bacc 100644 --- a/Modules/Sources/PointOfSale/Analytics/POSAnalyticsEvent.swift +++ b/Modules/Sources/PointOfSale/Analytics/POSAnalyticsEvent.swift @@ -404,3 +404,34 @@ public extension PaymentMethod { } } } + +extension WooAnalyticsEvent { + struct Orders { + // MARK: - Order Creation Events + + /// Matches errors on Android for consistency + /// Only coupon tracking is relevant for now + enum OrderCreationErrorType: String { + case invalidCoupon = "INVALID_COUPON" + } + + static func orderCreationFailed( + usesGiftCard: Bool, + errorContext: String, + errorDescription: String, + errorType: OrderCreationErrorType? = nil + ) -> WooAnalyticsEvent { + var properties: [String: WooAnalyticsEventPropertyType] = [ + "use_gift_card": usesGiftCard, + "error_context": errorContext, + "error_description": errorDescription + ] + + if let errorType { + properties["error_type"] = errorType.rawValue + } + + return WooAnalyticsEvent(statName: .orderCreationFailed, properties: properties) + } + } +} diff --git a/Modules/Sources/PointOfSale/DependencyProviders/POSDependencyProviding.swift b/Modules/Sources/PointOfSale/DependencyProviders/POSDependencyProviding.swift index a7d9573d554..c4dc71a6f46 100644 --- a/Modules/Sources/PointOfSale/DependencyProviders/POSDependencyProviding.swift +++ b/Modules/Sources/PointOfSale/DependencyProviders/POSDependencyProviding.swift @@ -1,17 +1,19 @@ import Foundation +import SwiftUI import WooFoundation import Experiments import protocol Yosemite.Action import struct Yosemite.Site /// Main dependency provider protocol for POS module -/// This abstracts away direct ServiceLocator access +/// This abstracts away dependencies from the main Woo app public protocol POSDependencyProviding { var analytics: POSAnalyticsProviding { get } var currency: POSCurrencySettingsProviding { get } var featureFlags: POSFeatureFlagProviding { get } - var session: POSSessionManagerProviding { get } var connectivity: POSConnectivityProviding { get } + var externalNavigation: POSExternalNavigationProviding { get } + var externalViews: POSExternalViewProviding { get } } public protocol POSAnalyticsProviding { @@ -21,10 +23,6 @@ public protocol POSAnalyticsProviding { func track(_ stat: WooAnalyticsStat) } -public protocol POSSessionManagerProviding { - var defaultSite: Site? { get } -} - public protocol POSFeatureFlagProviding { func isFeatureFlagEnabled(_ flag: FeatureFlag) -> Bool } @@ -36,3 +34,13 @@ public protocol POSCurrencySettingsProviding { public protocol POSConnectivityProviding { var connectivityObserver: ConnectivityObserver { get } } + +/// Navigation to the Woo app service abstraction +public protocol POSExternalNavigationProviding { + func navigateToCreateOrder() +} + +/// External view service abstraction +public protocol POSExternalViewProviding { + func createSupportFormView(isPresented: Binding) -> AnyView +} diff --git a/Modules/Sources/PointOfSale/Environment/POSEnvironmentKeys.swift b/Modules/Sources/PointOfSale/Environment/POSEnvironmentKeys.swift index 84df6f8aa7c..07455db1dc7 100644 --- a/Modules/Sources/PointOfSale/Environment/POSEnvironmentKeys.swift +++ b/Modules/Sources/PointOfSale/Environment/POSEnvironmentKeys.swift @@ -20,16 +20,21 @@ public struct POSFeatureFlagsKey: EnvironmentKey { public static let defaultValue: POSFeatureFlagProviding = EmptyPOSFeatureFlags() } -/// Environment key for POS session manager -public struct POSSessionManagerKey: EnvironmentKey { - public static let defaultValue: POSSessionManagerProviding = EmptyPOSSessionManager() -} - /// Environment key for POS connectivity public struct POSConnectivityKey: EnvironmentKey { public static let defaultValue: POSConnectivityProviding = EmptyPOSConnectivityProvider() } +/// Environment key for POS navigation service +public struct POSExternalNavigationKey: EnvironmentKey { + public static let defaultValue: POSExternalNavigationProviding = EmptyPOSExternalNavigation() +} + +/// Environment key for POS external view service +public struct POSExternalViewKey: EnvironmentKey { + public static let defaultValue: POSExternalViewProviding = EmptyPOSExternalView() +} + public extension EnvironmentValues { var posAnalytics: POSAnalyticsProviding { get { self[POSAnalyticsKey.self] } @@ -46,21 +51,26 @@ public extension EnvironmentValues { set { self[POSFeatureFlagsKey.self] = newValue } } - var posSession: POSSessionManagerProviding { - get { self[POSSessionManagerKey.self] } - set { self[POSSessionManagerKey.self] = newValue } - } - var posConnectivityProvider: POSConnectivityProviding { get { self[POSConnectivityKey.self] } set { self[POSConnectivityKey.self] = newValue } } + + var posExternalNavigation: POSExternalNavigationProviding { + get { self[POSExternalNavigationKey.self] } + set { self[POSExternalNavigationKey.self] = newValue } + } + + var posExternalViews: POSExternalViewProviding { + get { self[POSExternalViewKey.self] } + set { self[POSExternalViewKey.self] = newValue } + } } // MARK: - Empty Default Values -public struct EmptyPOSSessionManager: POSSessionManagerProviding { - public var defaultSite: Site? = nil +public struct EmptyPOSExternalNavigation: POSExternalNavigationProviding { + public func navigateToCreateOrder() {} public init() {} } @@ -94,3 +104,8 @@ public struct EmptyPOSAnalytics: POSAnalyticsProviding { public func track(_ stat: WooFoundationCore.WooAnalyticsStat, parameters: [String: WooAnalyticsEventPropertyType], error: any Error) {} public init() {} } + +public struct EmptyPOSExternalView: POSExternalViewProviding { + public func createSupportFormView(isPresented: Binding) -> AnyView { AnyView(EmptyView()) } + public init() {} +} diff --git a/Modules/Sources/PointOfSale/Extensions/UIImage+POS.swift b/Modules/Sources/PointOfSale/Extensions/UIImage+POS.swift new file mode 100644 index 00000000000..10e202e554c --- /dev/null +++ b/Modules/Sources/PointOfSale/Extensions/UIImage+POS.swift @@ -0,0 +1,24 @@ +import UIKit + +/// Point of Sale specific UIImage extensions +/// Contains only the UIImage extensions needed by the POS module to minimize external dependencies +extension UIImage { + + /// App icon (iPhone size) - used in receipt eligibility banner + /// + static var appIconDefault: UIImage { + return UIImage(named: "AppIcon60x60", in: .main, compatibleWith: nil)! + } + + /// Card Reader Update arrow - used in reader update progress + /// + static var cardReaderUpdateProgressArrow: UIImage { + return UIImage(named: "card-reader-update-progress-arrow", in: .main, compatibleWith: nil)! + } + + /// Card Reader Update checkmark - used in reader update progress completion + /// + static var cardReaderUpdateProgressCheckmark: UIImage { + return UIImage(named: "card-reader-update-progress-checkmark", in: .main, compatibleWith: nil)! + } +} diff --git a/WooCommerce/Classes/Extensions/Array+Helpers.swift b/Modules/Sources/WooFoundation/Extensions/Array+Helpers.swift similarity index 89% rename from WooCommerce/Classes/Extensions/Array+Helpers.swift rename to Modules/Sources/WooFoundation/Extensions/Array+Helpers.swift index 956166be410..6adb6987e46 100644 --- a/WooCommerce/Classes/Extensions/Array+Helpers.swift +++ b/Modules/Sources/WooFoundation/Extensions/Array+Helpers.swift @@ -1,9 +1,8 @@ import Foundation - // MARK: - Array Helpers // -extension Array { +public extension Array { /// Removes and returns the first element in the array. If any! /// mutating func popFirst() -> Element? { @@ -27,7 +26,7 @@ extension Array { // MARK: - Sequence Helpers // -extension Sequence { +public extension Sequence { /// Get the keypaths for a elemtents in a sequence. /// func map(_ keyPath: KeyPath) -> [T] { @@ -40,12 +39,12 @@ extension Sequence { } } -extension Sequence where Element: Numeric { +public extension Sequence where Element: Numeric { /// Returns the sum of all elements in the collection. func sum() -> Element { return reduce(0, +) } } -extension Sequence where Element: Equatable { +public extension Sequence where Element: Equatable { /// Returns the sequence with any duplicate elements after the first one removed. func removingDuplicates() -> [Element] { var result = [Element]() diff --git a/Modules/Sources/WooFoundation/UI Components/SafariView.swift b/Modules/Sources/WooFoundation/UI Components/SafariView.swift new file mode 100644 index 00000000000..ef6c268295d --- /dev/null +++ b/Modules/Sources/WooFoundation/UI Components/SafariView.swift @@ -0,0 +1,23 @@ +import SwiftUI +import SafariServices + +/// SwiftUI interface for UIKit SFSafariViewController +/// Provides a visible interface for web browsing, and Safari features +/// +public struct SafariView: UIViewControllerRepresentable { + + public let url: URL + + public init(url: URL) { + self.url = url + } + + public func makeUIViewController(context: UIViewControllerRepresentableContext) -> SFSafariViewController { + return SFSafariViewController(url: url) + } + + public func updateUIViewController(_ uiViewController: SFSafariViewController, + context: UIViewControllerRepresentableContext) { + + } +} diff --git a/WooCommerce/Classes/ViewRelated/ReusableViews/SwiftUI Components/IndefiniteCircularProgressViewStyle.swift b/Modules/Sources/WooFoundation/Utilities/IndefiniteCircularProgressViewStyle.swift similarity index 71% rename from WooCommerce/Classes/ViewRelated/ReusableViews/SwiftUI Components/IndefiniteCircularProgressViewStyle.swift rename to Modules/Sources/WooFoundation/Utilities/IndefiniteCircularProgressViewStyle.swift index 5aed02935ad..7c0c1f661db 100644 --- a/WooCommerce/Classes/ViewRelated/ReusableViews/SwiftUI Components/IndefiniteCircularProgressViewStyle.swift +++ b/Modules/Sources/WooFoundation/Utilities/IndefiniteCircularProgressViewStyle.swift @@ -15,6 +15,28 @@ public struct IndefiniteCircularProgressViewStyle: ProgressViewStyle { @State private var viewRotation: Angle = .radians(0) @State private var arcTimer: Timer? + public init( + size: CGFloat, + lineWidth: CGFloat = Constants.lineWidth, + lineCap: CGLineCap = .round, + circleColor: Color = Color(.primaryButtonBackground).opacity(Constants.backgroundOpacity), + fillColor: Color = Color(.primaryButtonBackground), + arcEnd: Double = Constants.initialArcEnd, + rotation: Angle = Constants.threeQuarterRotation, + viewRotation: Angle = .radians(0), + arcTimer: Timer? = nil + ) { + self.size = size + self.lineWidth = lineWidth + self.lineCap = lineCap + self.circleColor = circleColor + self.fillColor = fillColor + self.arcEnd = arcEnd + self.rotation = rotation + self.viewRotation = viewRotation + self.arcTimer = arcTimer + } + public func makeBody(configuration: ProgressViewStyleConfiguration) -> some View { VStack { ZStack { @@ -78,17 +100,17 @@ public struct IndefiniteCircularProgressViewStyle: ProgressViewStyle { } } -private extension IndefiniteCircularProgressViewStyle { +public extension IndefiniteCircularProgressViewStyle { enum Constants { - static let lineWidth: CGFloat = 10.0 - static let backgroundOpacity: CGFloat = 0.2 + public static let lineWidth: CGFloat = 10.0 + public static let backgroundOpacity: CGFloat = 0.2 - static let initialArcStart: Double = 0 - static let initialArcEnd: Double = 0.05 - static let fullCircle: Double = 1 + public static let initialArcStart: Double = 0 + public static let initialArcEnd: Double = 0.05 + public static let fullCircle: Double = 1 - static let threeQuarterRotation: Angle = .radians((9 * Double.pi)/6) - static let fullRotation: Angle = .radians(Double.pi * 2) + public static let threeQuarterRotation: Angle = .radians((9 * Double.pi)/6) + public static let fullRotation: Angle = .radians(Double.pi * 2) } enum Localization { diff --git a/WooCommerce/Classes/ViewRelated/ReusableViews/SwiftUI Components/KeyboardObserver.swift b/Modules/Sources/WooFoundation/Utilities/KeyboardObserver.swift similarity index 87% rename from WooCommerce/Classes/ViewRelated/ReusableViews/SwiftUI Components/KeyboardObserver.swift rename to Modules/Sources/WooFoundation/Utilities/KeyboardObserver.swift index 4e33dd8503e..378e9200413 100644 --- a/WooCommerce/Classes/ViewRelated/ReusableViews/SwiftUI Components/KeyboardObserver.swift +++ b/Modules/Sources/WooFoundation/Utilities/KeyboardObserver.swift @@ -3,22 +3,22 @@ import Combine @available(iOS 17.0, *) @Observable -final class KeyboardObserver { - private(set) var isKeyboardVisible: Bool = false - private(set) var keyboardHeight: CGFloat = 0 +public final class KeyboardObserver { + private(set) public var isKeyboardVisible: Bool = false + private(set) public var keyboardHeight: CGFloat = 0 /// When an external keyboard is in use, iPadOS shows a quicktype bar at the bottom of the screen. /// This is reported as a keyboard with height, so `isKeyboardVisible` will be true and /// keyboard height will be > 0. /// However, it's much less of an impingement on the view, so there may be no modification to the view required. /// `isFullSizeKeyboardVisible` is true when the full software keyboard is shown. - var isFullSizeKeyboardVisible: Bool { + public var isFullSizeKeyboardVisible: Bool { return keyboardHeight > Constants.hardwareKeyboardHelperBarHeightThreshold } private var cancellables = Set() - init() { + public init() { NotificationCenter.Publisher(center: .default, name: UIResponder.keyboardWillShowNotification) .merge(with: NotificationCenter.Publisher(center: .default, name: UIResponder.keyboardDidShowNotification)) .receive(on: DispatchQueue.main) @@ -64,7 +64,7 @@ private struct KeyboardObserverKey: EnvironmentKey { } @available(iOS 17.0, *) -extension EnvironmentValues { +public extension EnvironmentValues { var keyboardObserver: KeyboardObserver { get { self[KeyboardObserverKey.self] } set { self[KeyboardObserverKey.self] = newValue } @@ -72,16 +72,16 @@ extension EnvironmentValues { } @available(iOS 17.0, *) -struct KeyboardObserverProvider: ViewModifier { +public struct KeyboardObserverProvider: ViewModifier { @State private var observer = KeyboardObserver() - func body(content: Content) -> some View { + public func body(content: Content) -> some View { content.environment(\.keyboardObserver, observer) } } @available(iOS 17.0, *) -extension View { +public extension View { func injectKeyboardObserver() -> some View { modifier(KeyboardObserverProvider()) } diff --git a/WooCommerce/Classes/ViewRelated/ReusableViews/SwiftUI Components/ScrollableVStack.swift b/Modules/Sources/WooFoundation/Utilities/ScrollableVStack.swift similarity index 92% rename from WooCommerce/Classes/ViewRelated/ReusableViews/SwiftUI Components/ScrollableVStack.swift rename to Modules/Sources/WooFoundation/Utilities/ScrollableVStack.swift index 307c285ac42..38fb82e6ed7 100644 --- a/WooCommerce/Classes/ViewRelated/ReusableViews/SwiftUI Components/ScrollableVStack.swift +++ b/Modules/Sources/WooFoundation/Utilities/ScrollableVStack.swift @@ -1,14 +1,15 @@ import SwiftUI +import struct WooFoundation.ScrollableVStack /// Wraps a VStack inside a ScrollView, ensuring the content expands to fill the available space /// -struct ScrollableVStack: View { +public struct ScrollableVStack: View { let alignment: HorizontalAlignment let padding: CGFloat let spacing: CGFloat? let content: Content - init( + public init( alignment: HorizontalAlignment = .center, padding: CGFloat = 24, spacing: CGFloat? = nil, @@ -20,7 +21,7 @@ struct ScrollableVStack: View { self.content = content() } - var body: some View { + public var body: some View { GeometryReader { geometry in ScrollView { VStack(alignment: alignment, spacing: spacing) { diff --git a/WooCommerce/Classes/Tools/VersionHelpers.swift b/Modules/Sources/WooFoundation/Utilities/VersionHelpers.swift similarity index 93% rename from WooCommerce/Classes/Tools/VersionHelpers.swift rename to Modules/Sources/WooFoundation/Utilities/VersionHelpers.swift index c7bfa61ee0c..578dbb83978 100644 --- a/WooCommerce/Classes/Tools/VersionHelpers.swift +++ b/Modules/Sources/WooFoundation/Utilities/VersionHelpers.swift @@ -2,21 +2,21 @@ import Foundation /// Helpers for working with versions (e.g. comparing two version strings) /// -final class VersionHelpers { +public final class VersionHelpers { /// Compares two strings as versions using the same approach as PHP `version_compare`. /// https://www.php.net/manual/en/function.version-compare.php /// /// - Notable parameters: /// - includesDevAndBetaVersions: If true, the version string is considered supported if it contains the minimumRequired version /// e.g. "5.0.0-beta1" >= "5.0.0". - static func isVersionSupported(version: String, minimumRequired: String, includesDevAndBetaVersions: Bool = false) -> Bool { + public static func isVersionSupported(version: String, minimumRequired: String, includesDevAndBetaVersions: Bool = false) -> Bool { if includesDevAndBetaVersions && version.contains(minimumRequired) { return true } return VersionHelpers.compare(version, minimumRequired) != .orderedAscending } - static func isVersionSupported(version: String, minimumRequired: String, maximumPermitted: String) -> Bool { + public static func isVersionSupported(version: String, minimumRequired: String, maximumPermitted: String) -> Bool { VersionHelpers.compare(version, minimumRequired) != .orderedAscending && VersionHelpers.compare(version, maximumPermitted) != .orderedDescending } @@ -28,7 +28,7 @@ final class VersionHelpers { /// Returns `orderedSame` if the lhs version is the same as the rhs /// Returns `orderedDescending` if the lhs version is newer than the rhs /// - static func compare(_ lhs: String, _ rhs: String) -> ComparisonResult { + public static func compare(_ lhs: String, _ rhs: String) -> ComparisonResult { let leftComponents = versionComponents(of: lhs) let rightComponents = versionComponents(of: rhs) let maxComponents = max(leftComponents.count, rightComponents.count) diff --git a/WooCommerce/Classes/View Modifiers/View+AutofocusTextModifier.swift b/Modules/Sources/WooFoundation/ViewModifiers/View+AutofocusTextModifier.swift similarity index 81% rename from WooCommerce/Classes/View Modifiers/View+AutofocusTextModifier.swift rename to Modules/Sources/WooFoundation/ViewModifiers/View+AutofocusTextModifier.swift index 864ce5789d2..3303bb798d1 100644 --- a/WooCommerce/Classes/View Modifiers/View+AutofocusTextModifier.swift +++ b/Modules/Sources/WooFoundation/ViewModifiers/View+AutofocusTextModifier.swift @@ -2,11 +2,13 @@ import SwiftUI /// Autofocus for `TextField` and `TextEditor` in iOS 15 and later /// -struct AutofocusTextModifier: ViewModifier { +public struct AutofocusTextModifier: ViewModifier { @FocusState private var textFieldIsFocused: Bool - func body(content: Content) -> some View { + public init() {} + + public func body(content: Content) -> some View { content .focused($textFieldIsFocused) .onAppear { @@ -21,7 +23,7 @@ struct AutofocusTextModifier: ViewModifier { // MARK: View extension -extension View { +public extension View { /// Autofocus in `TextField` and `TextEditor` is available only for iOS15+ /// diff --git a/WooCommerce/Classes/View Modifiers/View+Conditionals.swift b/Modules/Sources/WooFoundation/ViewModifiers/View+Conditionals.swift similarity index 97% rename from WooCommerce/Classes/View Modifiers/View+Conditionals.swift rename to Modules/Sources/WooFoundation/ViewModifiers/View+Conditionals.swift index 09defe072b9..f62ddc18d00 100644 --- a/WooCommerce/Classes/View Modifiers/View+Conditionals.swift +++ b/Modules/Sources/WooFoundation/ViewModifiers/View+Conditionals.swift @@ -1,6 +1,6 @@ import SwiftUI -extension View { +public extension View { /// Renders a view if the provided `condition` is met. /// If the `condition` is not met, an `nil` will be used in place of the receiver view. /// diff --git a/WooCommerce/Classes/View Modifiers/View+Measurements.swift b/Modules/Sources/WooFoundation/ViewModifiers/View+Measurements.swift similarity index 99% rename from WooCommerce/Classes/View Modifiers/View+Measurements.swift rename to Modules/Sources/WooFoundation/ViewModifiers/View+Measurements.swift index b1d7cbeec99..aea2cbab08f 100644 --- a/WooCommerce/Classes/View Modifiers/View+Measurements.swift +++ b/Modules/Sources/WooFoundation/ViewModifiers/View+Measurements.swift @@ -1,6 +1,6 @@ import SwiftUI -extension View { +public extension View { /// Measures the height of a view and calls the provided callback with the height value. /// The callback is called both when the view first appears and whenever its height changes. /// If the view contains a list, consider wrapping it in a VStack to ensure the height updates are emitted as a group diff --git a/WooCommerce/Classes/View Modifiers/View+RoundedBorder.swift b/Modules/Sources/WooFoundation/ViewModifiers/View+RoundedBorder.swift similarity index 62% rename from WooCommerce/Classes/View Modifiers/View+RoundedBorder.swift rename to Modules/Sources/WooFoundation/ViewModifiers/View+RoundedBorder.swift index 06759ccd2ac..5901378cb29 100644 --- a/WooCommerce/Classes/View Modifiers/View+RoundedBorder.swift +++ b/Modules/Sources/WooFoundation/ViewModifiers/View+RoundedBorder.swift @@ -1,13 +1,20 @@ import SwiftUI /// Custom view modifier for applying a rounded border to a view. -struct RoundedBorder: ViewModifier { - let cornerRadius: CGFloat - let lineColor: Color - let lineWidth: CGFloat - let dashed: Bool +public struct RoundedBorder: ViewModifier { + public let cornerRadius: CGFloat + public let lineColor: Color + public let lineWidth: CGFloat + public let dashed: Bool - func body(content: Content) -> some View { + public init(cornerRadius: CGFloat, lineColor: Color, lineWidth: CGFloat, dashed: Bool) { + self.cornerRadius = cornerRadius + self.lineColor = lineColor + self.lineWidth = lineWidth + self.dashed = dashed + } + + public func body(content: Content) -> some View { content .overlay { RoundedRectangle(cornerRadius: cornerRadius) @@ -24,7 +31,7 @@ private extension RoundedBorder { } } -extension View { +public extension View { /// Applies a rounded border to a view. func roundedBorder(cornerRadius: CGFloat, lineColor: Color, lineWidth: CGFloat, dashed: Bool = false) -> some View { self.modifier(RoundedBorder(cornerRadius: cornerRadius, lineColor: lineColor, lineWidth: lineWidth, dashed: dashed)) diff --git a/WooCommerce/Classes/View Modifiers/View+ScrollModifiers.swift b/Modules/Sources/WooFoundation/ViewModifiers/View+ScrollModifiers.swift similarity index 87% rename from WooCommerce/Classes/View Modifiers/View+ScrollModifiers.swift rename to Modules/Sources/WooFoundation/ViewModifiers/View+ScrollModifiers.swift index d9b2ff30b2c..984a5adab8c 100644 --- a/WooCommerce/Classes/View Modifiers/View+ScrollModifiers.swift +++ b/Modules/Sources/WooFoundation/ViewModifiers/View+ScrollModifiers.swift @@ -1,10 +1,10 @@ import SwiftUI /// Preference key for communicating sizes -struct SizePreferenceKey: PreferenceKey { - static var defaultValue: CGSize? = nil +public struct SizePreferenceKey: PreferenceKey { + public static var defaultValue: CGSize? = nil - static func reduce(value: inout CGSize?, nextValue: () -> CGSize?) { + public static func reduce(value: inout CGSize?, nextValue: () -> CGSize?) { // Take the response of the first child which updates the key. Disallow further updates from its children. value = value ?? nextValue() } @@ -12,11 +12,11 @@ struct SizePreferenceKey: PreferenceKey { /// View modifier that conditionally wraps the `content` in a `ScrollView` if the `content` height exceeds the view height. /// -struct ConditionalVerticalScrollModifier: ViewModifier { +public struct ConditionalVerticalScrollModifier: ViewModifier { /// Defines if the content should scroll or not. @State private var shouldScroll: Bool = false - func body(content: Content) -> some View { + public func body(content: Content) -> some View { GeometryReader { parentGeometry in Group { if shouldScroll { @@ -52,7 +52,7 @@ struct ConditionalVerticalScrollModifier: ViewModifier { // MARK: View Extensions -extension View { +public extension View { /// Allows the view to scroll vertically when the content height is greater than its parent height. /// func scrollVerticallyIfNeeded() -> some View { diff --git a/Modules/Sources/WooFoundation/ViewModifiers/View+SizeTracker.swift b/Modules/Sources/WooFoundation/ViewModifiers/View+SizeTracker.swift new file mode 100644 index 00000000000..16bc3c0abcb --- /dev/null +++ b/Modules/Sources/WooFoundation/ViewModifiers/View+SizeTracker.swift @@ -0,0 +1,28 @@ +import SwiftUI + +public struct SizeTracker: ViewModifier { + @Binding var size: CGSize + + public init(size: Binding) { + self._size = size + } + + public func body(content: Content) -> some View { + content + .background(GeometryReader { proxy in + Color.clear + .onAppear { + self.size = proxy.size + } + .onChange(of: proxy.size) { newSize in + self.size = newSize + } + }) + } +} + +public extension View { + func trackSize(size: Binding) -> some View { + modifier(SizeTracker(size: size)) + } +} diff --git a/WooCommerce/Classes/ViewRelated/ReusableViews/SwiftUI Components/TextFieldStyles.swift b/Modules/Sources/WooFoundation/ViewModifiers/WooRoundedBorderTextFieldStyle.swift similarity index 90% rename from WooCommerce/Classes/ViewRelated/ReusableViews/SwiftUI Components/TextFieldStyles.swift rename to Modules/Sources/WooFoundation/ViewModifiers/WooRoundedBorderTextFieldStyle.swift index cdbfde1bc52..9dab8b65486 100644 --- a/WooCommerce/Classes/ViewRelated/ReusableViews/SwiftUI Components/TextFieldStyles.swift +++ b/Modules/Sources/WooFoundation/ViewModifiers/WooRoundedBorderTextFieldStyle.swift @@ -1,7 +1,7 @@ import SwiftUI /// Text field has a rounded border that has a thicker border and brighter border color when the field is focused. -struct WooRoundedBorderTextFieldStyle: TextFieldStyle { +public struct WooRoundedBorderTextFieldStyle: TextFieldStyle { private let focused: Bool private let focusedBorderColor: Color private let unfocusedBorderColor: Color @@ -19,7 +19,7 @@ struct WooRoundedBorderTextFieldStyle: TextFieldStyle { /// - insets: The insets between the background border and the text input. /// - height: An optional fixed height for the field. /// - content: Optional closure to wrap the text field content. - init(focused: Bool, + public init(focused: Bool, focusedBorderColor: Color = Defaults.focusedBorderColor, unfocusedBorderColor: Color = Defaults.unfocusedBorderColor, backgroundColor: Color = .clear, @@ -37,7 +37,7 @@ struct WooRoundedBorderTextFieldStyle: TextFieldStyle { self.content = content } - func _body(configuration: TextField) -> some View { + public func _body(configuration: TextField) -> some View { let styledContent = content?(configuration) ?? AnyView(configuration) styledContent @@ -53,11 +53,11 @@ struct WooRoundedBorderTextFieldStyle: TextFieldStyle { } } -extension WooRoundedBorderTextFieldStyle { +public extension WooRoundedBorderTextFieldStyle { enum Defaults { - static let focusedBorderColor: Color = .init(uiColor: .brand) - static let unfocusedBorderColor: Color = .gray - static let insets = EdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10) + public static let focusedBorderColor: Color = .init(.brand) + public static let unfocusedBorderColor: Color = .gray + public static let insets = EdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10) } } diff --git a/Modules/Sources/WooFoundationCore/String+Helpers.swift b/Modules/Sources/WooFoundationCore/String+Helpers.swift new file mode 100644 index 00000000000..50bbebb98db --- /dev/null +++ b/Modules/Sources/WooFoundationCore/String+Helpers.swift @@ -0,0 +1,51 @@ +import Foundation + +/// String: Helper Methods +/// +public extension String { + + /// Helper method to provide the singular or plural (formatted) version of a + /// string based on a count. + /// + /// - Parameters: + /// - count: Number of 'things' in the string + /// - singular: Singular version of localized string — used if `count` is 1 + /// - plural: Plural version of localized string — used if `count` is greater than 1 + /// - Returns: Singular or plural version of string based on `count` param + /// + /// NOTE: String params _must_ include `%ld` placeholder (count will be placed there). + /// + static func pluralize(_ count: Int, singular: String, plural: String) -> String { + if count == 1 { + return String.localizedStringWithFormat(singular, count) + } else { + return String.localizedStringWithFormat(plural, count) + } + } + + /// Helper method to provide the singular or plural (formatted) version of a + /// string based on a count. + /// + /// - Parameters: + /// - count: Number of 'things' in the string + /// - singular: Singular version of localized string — used if `count` is 1 + /// - plural: Plural version of localized string — used if `count` is greater than 1 + /// - Returns: Singular or plural version of string based on `count` param + /// + /// NOTE: String params _must_ include `%@` placeholder (count will be placed there). + /// + static func pluralize(_ count: Decimal, singular: String, plural: String) -> String { + let stringCount = NSDecimalNumber(decimal: count).stringValue + + if count > 0 && count < 1 || count == 1 { + return String.localizedStringWithFormat(singular, stringCount) + } else { + return String.localizedStringWithFormat(plural, stringCount) + } + } + + /// A Boolean value indicating whether a string has characters. + var isNotEmpty: Bool { + return !isEmpty + } +} diff --git a/WooCommerce/Classes/ViewRelated/Orders/Order Creation/Synchronizer/OrderTotalsCalculator.swift b/Modules/Sources/Yosemite/Tools/Orders/OrderTotalsCalculator.swift similarity index 83% rename from WooCommerce/Classes/ViewRelated/Orders/Order Creation/Synchronizer/OrderTotalsCalculator.swift rename to Modules/Sources/Yosemite/Tools/Orders/OrderTotalsCalculator.swift index caaf50a5427..f420ebdf544 100644 --- a/WooCommerce/Classes/ViewRelated/Orders/Order Creation/Synchronizer/OrderTotalsCalculator.swift +++ b/Modules/Sources/Yosemite/Tools/Orders/OrderTotalsCalculator.swift @@ -1,10 +1,9 @@ import Foundation -import Yosemite import WooFoundation /// Helper to calculate the totals on an `Order`. /// -final class OrderTotalsCalculator { +final public class OrderTotalsCalculator { // MARK: Private properties private let order: Order @@ -27,7 +26,7 @@ final class OrderTotalsCalculator { /// Total value of all items on an order. /// - var itemsTotal: NSDecimalNumber { + public var itemsTotal: NSDecimalNumber { order.items .map { $0.subtotal } .compactMap { currencyFormatter.convertToDecimal($0) } @@ -36,7 +35,7 @@ final class OrderTotalsCalculator { /// Total value of all fee lines on an order. /// - var feesTotal: NSDecimalNumber { + public var feesTotal: NSDecimalNumber { order.fees .map { $0.total } .compactMap { currencyFormatter.convertToDecimal($0) } @@ -45,7 +44,7 @@ final class OrderTotalsCalculator { /// Total value of discounts, including coupons and product discounts. /// - var discountTotal: NSDecimalNumber { + public var discountTotal: NSDecimalNumber { let itemsDiscountedTotal = order.items .map { $0.total } .compactMap { currencyFormatter.convertToDecimal($0) } @@ -56,18 +55,18 @@ final class OrderTotalsCalculator { /// Order total /// - var orderTotal: NSDecimalNumber { + public var orderTotal: NSDecimalNumber { itemsTotal.adding(shippingTotal).adding(feesTotal).adding(taxesTotal).subtracting(discountTotal) } - init(for order: Order, using currencyFormatter: CurrencyFormatter) { + public init(for order: Order, using currencyFormatter: CurrencyFormatter) { self.order = order self.currencyFormatter = currencyFormatter } /// Returns a copy of the order with a new, locally calculated order total. /// - func updateOrderTotal() -> Order { + public func updateOrderTotal() -> Order { return order.copy(total: orderTotal.stringValue) } } diff --git a/WooCommerce/WooCommerceTests/Extensions/VersionHelpersTests.swift b/Modules/Tests/WooFoundationTests/VersionHelpersTests.swift similarity index 99% rename from WooCommerce/WooCommerceTests/Extensions/VersionHelpersTests.swift rename to Modules/Tests/WooFoundationTests/VersionHelpersTests.swift index 35ef2cc7873..1e63cfa0d4a 100644 --- a/WooCommerce/WooCommerceTests/Extensions/VersionHelpersTests.swift +++ b/Modules/Tests/WooFoundationTests/VersionHelpersTests.swift @@ -1,5 +1,5 @@ import Testing -@testable import WooCommerce +@testable import WooFoundation /// VersionHelpers Unit Tests /// diff --git a/WooCommerce/WooCommerceTests/ViewRelated/Orders/Order Creation/Synchronizer/OrderTotalsCalculatorTests.swift b/Modules/Tests/YosemiteTests/Tools/Orders/OrderTotalsCalculatorTests.swift similarity index 99% rename from WooCommerce/WooCommerceTests/ViewRelated/Orders/Order Creation/Synchronizer/OrderTotalsCalculatorTests.swift rename to Modules/Tests/YosemiteTests/Tools/Orders/OrderTotalsCalculatorTests.swift index d6658d9278b..66164bd4aea 100644 --- a/WooCommerce/WooCommerceTests/ViewRelated/Orders/Order Creation/Synchronizer/OrderTotalsCalculatorTests.swift +++ b/Modules/Tests/YosemiteTests/Tools/Orders/OrderTotalsCalculatorTests.swift @@ -1,7 +1,5 @@ import XCTest - import WooFoundation -@testable import WooCommerce @testable import Yosemite class OrderTotalsCalculatorTests: XCTestCase { diff --git a/WooCommerce/Classes/Authentication/Jetpack Setup/Native Jetpack Setup/JetpackSetupInterruptedView.swift b/WooCommerce/Classes/Authentication/Jetpack Setup/Native Jetpack Setup/JetpackSetupInterruptedView.swift index 14c990a76ca..3e687602ec5 100644 --- a/WooCommerce/Classes/Authentication/Jetpack Setup/Native Jetpack Setup/JetpackSetupInterruptedView.swift +++ b/WooCommerce/Classes/Authentication/Jetpack Setup/Native Jetpack Setup/JetpackSetupInterruptedView.swift @@ -1,4 +1,5 @@ import SwiftUI +import struct WooFoundation.ScrollableVStack /// View to be displayed when the Jetpack connection flow is dismissed. /// This screen is used only in the Jetpack setup flow for non-JCP sites. diff --git a/WooCommerce/Classes/Extensions/String+Helpers.swift b/WooCommerce/Classes/Extensions/String+Helpers.swift index 902b437a65d..fd5a30343ec 100644 --- a/WooCommerce/Classes/Extensions/String+Helpers.swift +++ b/WooCommerce/Classes/Extensions/String+Helpers.swift @@ -5,47 +5,6 @@ import UIKit /// String: Helper Methods /// extension String { - - /// Helper method to provide the singular or plural (formatted) version of a - /// string based on a count. - /// - /// - Parameters: - /// - count: Number of 'things' in the string - /// - singular: Singular version of localized string — used if `count` is 1 - /// - plural: Plural version of localized string — used if `count` is greater than 1 - /// - Returns: Singular or plural version of string based on `count` param - /// - /// NOTE: String params _must_ include `%ld` placeholder (count will be placed there). - /// - static func pluralize(_ count: Int, singular: String, plural: String) -> String { - if count == 1 { - return String.localizedStringWithFormat(singular, count) - } else { - return String.localizedStringWithFormat(plural, count) - } - } - - /// Helper method to provide the singular or plural (formatted) version of a - /// string based on a count. - /// - /// - Parameters: - /// - count: Number of 'things' in the string - /// - singular: Singular version of localized string — used if `count` is 1 - /// - plural: Plural version of localized string — used if `count` is greater than 1 - /// - Returns: Singular or plural version of string based on `count` param - /// - /// NOTE: String params _must_ include `%@` placeholder (count will be placed there). - /// - static func pluralize(_ count: Decimal, singular: String, plural: String) -> String { - let stringCount = NSDecimalNumber(decimal: count).stringValue - - if count > 0 && count < 1 || count == 1 { - return String.localizedStringWithFormat(singular, stringCount) - } else { - return String.localizedStringWithFormat(plural, stringCount) - } - } - /// Helper method to remove the last newline character in a given string. /// /// - Parameters: @@ -65,11 +24,6 @@ extension String { return newText } - /// A Boolean value indicating whether a string has characters. - var isNotEmpty: Bool { - return !isEmpty - } - /// Get quotation marks from Locale static var quotes: (String, String) { guard diff --git a/WooCommerce/Classes/Extensions/String+ProductQuantityRules.swift b/WooCommerce/Classes/Extensions/String+ProductQuantityRules.swift index 4adfd665547..cb91c4f2e10 100644 --- a/WooCommerce/Classes/Extensions/String+ProductQuantityRules.swift +++ b/WooCommerce/Classes/Extensions/String+ProductQuantityRules.swift @@ -1,4 +1,5 @@ import Foundation +import WooFoundation extension String { /// Returns whether the product quantity rule (e.g. mininum or maximum quantities the product can be ordered) has a valid value diff --git a/WooCommerce/Classes/GoogleAds/GoogleAdsEligibilityChecker.swift b/WooCommerce/Classes/GoogleAds/GoogleAdsEligibilityChecker.swift index 5e9a3586502..c94fa1b7efc 100644 --- a/WooCommerce/Classes/GoogleAds/GoogleAdsEligibilityChecker.swift +++ b/WooCommerce/Classes/GoogleAds/GoogleAdsEligibilityChecker.swift @@ -1,6 +1,7 @@ import Foundation import Experiments import Yosemite +import class WooFoundation.VersionHelpers /// Interface for checking if a site is eligible for creating Google ads campaigns from the app. /// diff --git a/WooCommerce/Classes/POS/Card Present Payments/CardPresentPaymentBluetoothReaderConnectionAlertsProvider.swift b/WooCommerce/Classes/POS/Adaptors/Card Present Payments/CardPresentPaymentBluetoothReaderConnectionAlertsProvider.swift similarity index 100% rename from WooCommerce/Classes/POS/Card Present Payments/CardPresentPaymentBluetoothReaderConnectionAlertsProvider.swift rename to WooCommerce/Classes/POS/Adaptors/Card Present Payments/CardPresentPaymentBluetoothReaderConnectionAlertsProvider.swift diff --git a/WooCommerce/Classes/POS/Card Present Payments/CardPresentPaymentInvalidatablePaymentOrchestrator.swift b/WooCommerce/Classes/POS/Adaptors/Card Present Payments/CardPresentPaymentInvalidatablePaymentOrchestrator.swift similarity index 100% rename from WooCommerce/Classes/POS/Card Present Payments/CardPresentPaymentInvalidatablePaymentOrchestrator.swift rename to WooCommerce/Classes/POS/Adaptors/Card Present Payments/CardPresentPaymentInvalidatablePaymentOrchestrator.swift diff --git a/WooCommerce/Classes/POS/Adaptors/Card Present Payments/CardPresentPaymentOnboardingAdaptor.swift b/WooCommerce/Classes/POS/Adaptors/Card Present Payments/CardPresentPaymentOnboardingAdaptor.swift index 7009da94612..1b7ada449f2 100644 --- a/WooCommerce/Classes/POS/Adaptors/Card Present Payments/CardPresentPaymentOnboardingAdaptor.swift +++ b/WooCommerce/Classes/POS/Adaptors/Card Present Payments/CardPresentPaymentOnboardingAdaptor.swift @@ -1,6 +1,7 @@ import Foundation import Combine import protocol Yosemite.StoresManager +import SwiftUI /// This is really a re-implementation of the CardPresentPaymentsOnboardingPresenter, as it needs to take the calls to `showOnboardingIfRequired` and /// route the output to a SwiftUI view for display, rather than directly displaying on the viewController that's passed in. @@ -46,9 +47,15 @@ final class CardPresentPaymentsOnboardingPresenterAdaptor: CardPresentPaymentsOn } private func showOnboarding(readyToCollectPayment completion: @escaping () -> Void) { - onboardingScreenViewModelSubject.send(.showOnboarding(viewModel: onboardingViewModel, onCancel: { [weak self] in - self?.readinessSubscription = nil - })) + let onboardingViewModel = self.onboardingViewModel + onboardingScreenViewModelSubject.send(.showOnboarding( + factory: .init( + configuration: onboardingViewModel, + view: CardPresentPaymentsOnboardingView(viewModel: onboardingViewModel)), + onCancel: { [weak self] in + self?.readinessSubscription = nil + }) + ) readinessSubscription = readinessUseCase.$readiness .subscribe(on: DispatchQueue.main) @@ -70,3 +77,5 @@ final class CardPresentPaymentsOnboardingPresenterAdaptor: CardPresentPaymentsOn onboardingUseCase.refreshIfNecessary() } } + +extension CardPresentPaymentsOnboardingViewModel: CardPresentPaymentsOnboardingViewConfiguration {} diff --git a/WooCommerce/Classes/POS/Adaptors/Card Present Payments/CardPresentPaymentService.swift b/WooCommerce/Classes/POS/Adaptors/Card Present Payments/CardPresentPaymentService.swift index be0bab237f2..688060f1e96 100644 --- a/WooCommerce/Classes/POS/Adaptors/Card Present Payments/CardPresentPaymentService.swift +++ b/WooCommerce/Classes/POS/Adaptors/Card Present Payments/CardPresentPaymentService.swift @@ -52,8 +52,8 @@ final class CardPresentPaymentService: CardPresentPaymentFacade { paymentEventPublisher = onboardingAdaptor.onboardingScreenViewModelPublisher .map { onboardingEvent -> CardPresentPaymentEvent in switch onboardingEvent { - case let .showOnboarding(onboardingViewModel, onCancel): - return .showOnboarding(onboardingViewModel: onboardingViewModel, onCancel: onCancel) + case let .showOnboarding(factory, onCancel): + return .showOnboarding(factory: factory, onCancel: onCancel) case .onboardingComplete: return .idle } diff --git a/WooCommerce/Classes/POS/Card Present Payments/CardPresentPaymentTapToPayReaderConnectionAlertsProvider.swift b/WooCommerce/Classes/POS/Adaptors/Card Present Payments/CardPresentPaymentTapToPayReaderConnectionAlertsProvider.swift similarity index 100% rename from WooCommerce/Classes/POS/Card Present Payments/CardPresentPaymentTapToPayReaderConnectionAlertsProvider.swift rename to WooCommerce/Classes/POS/Adaptors/Card Present Payments/CardPresentPaymentTapToPayReaderConnectionAlertsProvider.swift diff --git a/WooCommerce/Classes/POS/Card Present Payments/CardPresentPaymentsConnectionControllerManager.swift b/WooCommerce/Classes/POS/Adaptors/Card Present Payments/CardPresentPaymentsConnectionControllerManager.swift similarity index 100% rename from WooCommerce/Classes/POS/Card Present Payments/CardPresentPaymentsConnectionControllerManager.swift rename to WooCommerce/Classes/POS/Adaptors/Card Present Payments/CardPresentPaymentsConnectionControllerManager.swift diff --git a/WooCommerce/Classes/POS/Card Present Payments/CardPresentPaymentsTransactionAlertsProvider.swift b/WooCommerce/Classes/POS/Adaptors/Card Present Payments/CardPresentPaymentsTransactionAlertsProvider.swift similarity index 100% rename from WooCommerce/Classes/POS/Card Present Payments/CardPresentPaymentsTransactionAlertsProvider.swift rename to WooCommerce/Classes/POS/Adaptors/Card Present Payments/CardPresentPaymentsTransactionAlertsProvider.swift diff --git a/WooCommerce/Classes/POS/Analytics/POSCollectOrderPaymentAnalytics.swift b/WooCommerce/Classes/POS/Adaptors/POSCollectOrderPaymentAnalyticsAdaptor.swift similarity index 95% rename from WooCommerce/Classes/POS/Analytics/POSCollectOrderPaymentAnalytics.swift rename to WooCommerce/Classes/POS/Adaptors/POSCollectOrderPaymentAnalyticsAdaptor.swift index 510253f308b..bf06ce8f042 100644 --- a/WooCommerce/Classes/POS/Analytics/POSCollectOrderPaymentAnalytics.swift +++ b/WooCommerce/Classes/POS/Adaptors/POSCollectOrderPaymentAnalyticsAdaptor.swift @@ -2,7 +2,9 @@ import Foundation import protocol WooFoundation.Analytics import Yosemite -final class POSCollectOrderPaymentAnalytics: POSCollectOrderPaymentAnalyticsTracking { +/// Overrides the default event tracking for card present payments on IPP in Order Creation flow +/// +final class POSCollectOrderPaymentAnalyticsAdaptor: POSCollectOrderPaymentAnalyticsTracking, CollectOrderPaymentAnalyticsTracking { private var customerInteractionStarted: Double = 0 private var orderSync: Double = 0 private var cardReaderReady: Double = 0 @@ -128,7 +130,7 @@ final class POSCollectOrderPaymentAnalytics: POSCollectOrderPaymentAnalyticsTrac } // Helpers -private extension POSCollectOrderPaymentAnalytics { +private extension POSCollectOrderPaymentAnalyticsAdaptor { func trackCurrentTime() -> Double { Date().timeIntervalSince1970 } diff --git a/WooCommerce/Classes/POS/Adaptors/POSServiceLocatorAdaptor.swift b/WooCommerce/Classes/POS/Adaptors/POSServiceLocatorAdaptor.swift index 3b0028b764d..1eaf9ae7bc1 100644 --- a/WooCommerce/Classes/POS/Adaptors/POSServiceLocatorAdaptor.swift +++ b/WooCommerce/Classes/POS/Adaptors/POSServiceLocatorAdaptor.swift @@ -1,5 +1,6 @@ import PointOfSale import WooFoundation +import SwiftUI import protocol Experiments.FeatureFlagService import enum Experiments.FeatureFlag import struct Yosemite.Site @@ -24,21 +25,21 @@ final class POSServiceLocatorAdaptor: POSDependencyProviding { POSFeatureFlagAdaptor() } - var session: POSSessionManagerProviding { - POSSessionManagerAdaptor() - } - var connectivity: POSConnectivityProviding { POSConnectivityAdaptor() } -} -private struct POSSessionManagerAdaptor: POSSessionManagerProviding { - var defaultSite: Site? { - return ServiceLocator.stores.sessionManager.defaultSite + var externalNavigation: POSExternalNavigationProviding { + POSExternalNavigationAdaptor() + } + + var externalViews: POSExternalViewProviding { + POSExternalViewAdaptor() } } +// MARK: - Individual Service Adaptors + private struct POSCurrencySettingsAdaptor: POSCurrencySettingsProviding { var currencySettings: CurrencySettings { ServiceLocator.currencySettings @@ -74,3 +75,19 @@ private struct POSConnectivityAdaptor: POSConnectivityProviding { ServiceLocator.connectivityObserver } } + +private struct POSExternalNavigationAdaptor: POSExternalNavigationProviding { + func navigateToCreateOrder() { + AppDelegate.shared.tabBarController?.navigate(to: OrdersDestination.createOrder) + } +} + +private struct POSExternalViewAdaptor: POSExternalViewProviding { + func createSupportFormView(isPresented: Binding) -> AnyView { + AnyView( + SupportForm(isPresented: isPresented, + viewModel: SupportFormViewModel(sourceTag: "pos", + defaultSite: ServiceLocator.stores.sessionManager.defaultSite)) + ) + } +} diff --git a/WooCommerce/Classes/POS/Analytics/POSCollectOrderPaymentAnalyticsTracking.swift b/WooCommerce/Classes/POS/Analytics/POSCollectOrderPaymentAnalyticsTracking.swift index 5dd4699bc9b..cbe1c90aebd 100644 --- a/WooCommerce/Classes/POS/Analytics/POSCollectOrderPaymentAnalyticsTracking.swift +++ b/WooCommerce/Classes/POS/Analytics/POSCollectOrderPaymentAnalyticsTracking.swift @@ -1,4 +1,4 @@ -protocol POSCollectOrderPaymentAnalyticsTracking: CollectOrderPaymentAnalyticsTracking { +protocol POSCollectOrderPaymentAnalyticsTracking { func trackCustomerInteractionStarted() func trackOrderSyncSuccess() func trackCardReaderReady() diff --git a/WooCommerce/Classes/POS/Card Present Payments/CardPresentPaymentError.swift b/WooCommerce/Classes/POS/Card Present Payments/CardPresentPaymentError.swift deleted file mode 100644 index 66c38f1d86f..00000000000 --- a/WooCommerce/Classes/POS/Card Present Payments/CardPresentPaymentError.swift +++ /dev/null @@ -1,10 +0,0 @@ -import Foundation - -enum CardPresentPaymentError: Error { - var retryApproach: CardPaymentRetryApproach { - .restart - } - - case unknownPaymentError(underlyingError: Error) - case unknownConnectionError(UnderlyingError: Error) -} diff --git a/WooCommerce/Classes/POS/Card Present Payments/CardPresentPaymentEvent.swift b/WooCommerce/Classes/POS/Card Present Payments/CardPresentPaymentEvent.swift index 38e21cf00a1..481317bdf78 100644 --- a/WooCommerce/Classes/POS/Card Present Payments/CardPresentPaymentEvent.swift +++ b/WooCommerce/Classes/POS/Card Present Payments/CardPresentPaymentEvent.swift @@ -3,5 +3,5 @@ import Foundation enum CardPresentPaymentEvent { case idle case show(eventDetails: CardPresentPaymentEventDetails) - case showOnboarding(onboardingViewModel: CardPresentPaymentsOnboardingViewModel, onCancel: () -> Void) + case showOnboarding(factory: CardPresentPaymentOnboardingViewFactory, onCancel: () -> Void) } diff --git a/WooCommerce/Classes/POS/Card Present Payments/CardPresentPaymentOnboardingPresentationEvent.swift b/WooCommerce/Classes/POS/Card Present Payments/CardPresentPaymentOnboardingPresentationEvent.swift index eba0d66548d..0db1974efda 100644 --- a/WooCommerce/Classes/POS/Card Present Payments/CardPresentPaymentOnboardingPresentationEvent.swift +++ b/WooCommerce/Classes/POS/Card Present Payments/CardPresentPaymentOnboardingPresentationEvent.swift @@ -1,6 +1,6 @@ import Foundation enum CardPresentPaymentOnboardingPresentationEvent { - case showOnboarding(viewModel: CardPresentPaymentsOnboardingViewModel, onCancel: () -> Void) + case showOnboarding(factory: CardPresentPaymentOnboardingViewFactory, onCancel: () -> Void) case onboardingComplete } diff --git a/WooCommerce/Classes/POS/Controllers/PointOfSaleOrderController.swift b/WooCommerce/Classes/POS/Controllers/PointOfSaleOrderController.swift index b64782fe5fe..06d516b6ac5 100644 --- a/WooCommerce/Classes/POS/Controllers/PointOfSaleOrderController.swift +++ b/WooCommerce/Classes/POS/Controllers/PointOfSaleOrderController.swift @@ -1,6 +1,7 @@ import Foundation import Observation import protocol Experiments.FeatureFlagService +import class WooFoundation.VersionHelpers import protocol Yosemite.POSOrderServiceProtocol import protocol Yosemite.POSReceiptServiceProtocol import protocol Yosemite.PluginsServiceProtocol @@ -18,6 +19,7 @@ import class Yosemite.PluginsService import enum WooFoundation.CurrencyCode import protocol WooFoundation.Analytics import enum Alamofire.AFError +import class Yosemite.OrderTotalsCalculator enum SyncOrderState { case newOrder diff --git a/WooCommerce/Classes/POS/Models/PointOfSaleAggregateModel.swift b/WooCommerce/Classes/POS/Models/PointOfSaleAggregateModel.swift index 0539790bede..a57dfa37985 100644 --- a/WooCommerce/Classes/POS/Models/PointOfSaleAggregateModel.swift +++ b/WooCommerce/Classes/POS/Models/PointOfSaleAggregateModel.swift @@ -24,7 +24,7 @@ protocol PointOfSaleAggregateModelProtocol { var paymentState: PointOfSalePaymentState { get } var cardPresentPaymentAlertViewModel: PointOfSaleCardPresentPaymentAlertType? { get set } var cardPresentPaymentInlineMessage: PointOfSaleCardPresentPaymentMessageType? { get } - var cardPresentPaymentOnboardingViewModel: CardPresentPaymentsOnboardingViewModel? { get set } + var cardPresentPaymentOnboardingViewFactory: CardPresentPaymentOnboardingViewFactory? { get set } func cancelCardPaymentsOnboarding() func trackCardPaymentsOnboardingShown() @@ -58,7 +58,7 @@ protocol PointOfSaleAggregateModelProtocol { private(set) var paymentState: PointOfSalePaymentState var cardPresentPaymentAlertViewModel: PointOfSaleCardPresentPaymentAlertType? private(set) var cardPresentPaymentInlineMessage: PointOfSaleCardPresentPaymentMessageType? - var cardPresentPaymentOnboardingViewModel: CardPresentPaymentsOnboardingViewModel? + var cardPresentPaymentOnboardingViewFactory: CardPresentPaymentOnboardingViewFactory? private var onOnboardingCancellation: (() -> Void)? private(set) var cart: Cart = .init() @@ -458,15 +458,15 @@ extension PointOfSaleAggregateModel { /// Called when the onboarding UI is dismissed. /// For external dismissal (tapping CTA to dismiss), this method is called twice - the first time to dismiss the onboarding UI - /// by setting `cardPresentPaymentOnboardingViewModel` to nil, the second time triggered by internal dismissal. + /// by setting `cardPresentPaymentOnboardingViewFactory` to nil, the second time triggered by internal dismissal. /// For internal dismissal (tapping outside the modal), this method is called once. /// This method is used to reset the internal state of the onboarding UI and track the dismissal event. func cancelCardPaymentsOnboarding() { - guard let onboardingViewModel = cardPresentPaymentOnboardingViewModel else { + guard let onboardingViewFactory = cardPresentPaymentOnboardingViewFactory else { return } - analytics.track(event: .PointOfSale.paymentsOnboardingDismissed(onboardingState: onboardingViewModel.state)) - cardPresentPaymentOnboardingViewModel = nil + analytics.track(event: .PointOfSale.paymentsOnboardingDismissed(onboardingState: onboardingViewFactory.configuration.state)) + cardPresentPaymentOnboardingViewFactory = nil onOnboardingCancellation?() } @@ -533,16 +533,16 @@ private extension PointOfSaleAggregateModel { .store(in: &cancellables) cardPresentPaymentService.paymentEventPublisher - .map { [weak self] event -> CardPresentPaymentsOnboardingViewModel? in + .map { [weak self] event -> CardPresentPaymentOnboardingViewFactory? in guard let self else { return nil } - guard case let .showOnboarding(viewModel, onCancel) = event else { + guard case let .showOnboarding(factory, onCancel) = event else { return nil } onOnboardingCancellation = onCancel - return viewModel + return factory } - .sink(receiveValue: { [weak self] onboardingViewModel in - self?.cardPresentPaymentOnboardingViewModel = onboardingViewModel + .sink(receiveValue: { [weak self] factory in + self?.cardPresentPaymentOnboardingViewFactory = factory }) .store(in: &cancellables) } diff --git a/WooCommerce/Classes/POS/Presentation/Barcode Scanner Setup/PointOfSaleBarcodeScannerSetup.swift b/WooCommerce/Classes/POS/Presentation/Barcode Scanner Setup/PointOfSaleBarcodeScannerSetup.swift index 4c183891400..4c00197205c 100644 --- a/WooCommerce/Classes/POS/Presentation/Barcode Scanner Setup/PointOfSaleBarcodeScannerSetup.swift +++ b/WooCommerce/Classes/POS/Presentation/Barcode Scanner Setup/PointOfSaleBarcodeScannerSetup.swift @@ -123,7 +123,7 @@ private extension PointOfSaleBarcodeScannerSetup { #if DEBUG @available(iOS 17.0, *) #Preview { - PointOfSaleBarcodeScannerSetup(isPresented: .constant(true), analytics: POSPreviewAnalytics()) + PointOfSaleBarcodeScannerSetup(isPresented: .constant(true), analytics: EmptyPOSAnalytics()) } #endif diff --git a/WooCommerce/Classes/POS/Presentation/CardReaderConnection/UI States/PointOfSaleItemListEmptyView.swift b/WooCommerce/Classes/POS/Presentation/CardReaderConnection/UI States/PointOfSaleItemListEmptyView.swift index cb444188d47..a1db41ac495 100644 --- a/WooCommerce/Classes/POS/Presentation/CardReaderConnection/UI States/PointOfSaleItemListEmptyView.swift +++ b/WooCommerce/Classes/POS/Presentation/CardReaderConnection/UI States/PointOfSaleItemListEmptyView.swift @@ -1,4 +1,5 @@ import SwiftUI +import struct WooFoundation.ScrollableVStack @available(iOS 17.0, *) struct PointOfSaleItemListEmptyView: View { diff --git a/WooCommerce/Classes/POS/Presentation/CardReaderConnection/UI States/PointOfSaleItemListErrorView.swift b/WooCommerce/Classes/POS/Presentation/CardReaderConnection/UI States/PointOfSaleItemListErrorView.swift index f952533be26..61c5ba55314 100644 --- a/WooCommerce/Classes/POS/Presentation/CardReaderConnection/UI States/PointOfSaleItemListErrorView.swift +++ b/WooCommerce/Classes/POS/Presentation/CardReaderConnection/UI States/PointOfSaleItemListErrorView.swift @@ -1,4 +1,5 @@ import SwiftUI +import struct WooFoundation.ScrollableVStack /// A view that displays an error message with a retry CTA when the list of POS items fails to load. @available(iOS 17.0, *) diff --git a/WooCommerce/Classes/POS/Presentation/Item Search/POSPreSearchView.swift b/WooCommerce/Classes/POS/Presentation/Item Search/POSPreSearchView.swift index 7d7f2999411..052661f4d0a 100644 --- a/WooCommerce/Classes/POS/Presentation/Item Search/POSPreSearchView.swift +++ b/WooCommerce/Classes/POS/Presentation/Item Search/POSPreSearchView.swift @@ -1,5 +1,6 @@ import SwiftUI import enum Yosemite.POSItem +import WooFoundation @available(iOS 17.0, *) struct POSPreSearchView: View { diff --git a/WooCommerce/Classes/POS/Presentation/Item Search/POSSearchTextFieldStyle.swift b/WooCommerce/Classes/POS/Presentation/Item Search/POSSearchTextFieldStyle.swift index 2cfb95ed0d8..b9708d6f3c8 100644 --- a/WooCommerce/Classes/POS/Presentation/Item Search/POSSearchTextFieldStyle.swift +++ b/WooCommerce/Classes/POS/Presentation/Item Search/POSSearchTextFieldStyle.swift @@ -1,4 +1,5 @@ import SwiftUI +import WooFoundation /// Text field style for search fields that includes a magnifier icon and clear button struct POSSearchTextFieldStyle: TextFieldStyle { diff --git a/WooCommerce/Classes/POS/Presentation/Item Selector/ChildItemList.swift b/WooCommerce/Classes/POS/Presentation/Item Selector/ChildItemList.swift index 60ef336943d..f25131e4eaf 100644 --- a/WooCommerce/Classes/POS/Presentation/Item Selector/ChildItemList.swift +++ b/WooCommerce/Classes/POS/Presentation/Item Selector/ChildItemList.swift @@ -178,7 +178,7 @@ private extension ChildItemList { analyticsTracker: PointOfSaleItemListAnalyticsTracker( sourceView: .variation, sourceViewType: .list, - analytics: POSPreviewAnalytics() + analytics: EmptyPOSAnalytics() )) } @@ -205,7 +205,7 @@ private extension ChildItemList { analyticsTracker: PointOfSaleItemListAnalyticsTracker( sourceView: .variation, sourceViewType: .list, - analytics: POSPreviewAnalytics() + analytics: EmptyPOSAnalytics() )) } diff --git a/WooCommerce/Classes/POS/Presentation/Payments Onboarding/PointOfSaleCardPresentPaymentOnboardingView.swift b/WooCommerce/Classes/POS/Presentation/Payments Onboarding/PointOfSaleCardPresentPaymentOnboardingView.swift index 105e2c0afde..4b28eeb8325 100644 --- a/WooCommerce/Classes/POS/Presentation/Payments Onboarding/PointOfSaleCardPresentPaymentOnboardingView.swift +++ b/WooCommerce/Classes/POS/Presentation/Payments Onboarding/PointOfSaleCardPresentPaymentOnboardingView.swift @@ -6,7 +6,7 @@ struct PointOfSaleCardPresentPaymentOnboardingView: View { var body: some View { VStack(spacing: Constants.verticalSpacing) { - CardPresentPaymentsOnboardingView(viewModel: viewModel.onboardingViewModel) + AnyView(viewModel.onboardingViewFactory.view) // Hides the navigation bar title `navigationTitle` in `CardPresentPaymentsOnboardingView`. .toolbar(.hidden) } @@ -31,6 +31,20 @@ private extension PointOfSaleCardPresentPaymentOnboardingView { } } + +#if DEBUG + +import enum Yosemite.CardPresentPaymentOnboardingState + +class PreviewOnboardingViewFactoryConfiguration: CardPresentPaymentsOnboardingViewConfiguration { + var showSupport: (() -> Void)? + var showURL: ((URL) -> Void)? + var state: CardPresentPaymentOnboardingState = .loading +} + #Preview { - PointOfSaleCardPresentPaymentOnboardingView(viewModel: .init(onboardingViewModel: .init(fixedState: .genericError), onDismissTap: nil)) + PointOfSaleCardPresentPaymentOnboardingView(viewModel: .init( + onboardingViewFactory: .init(configuration: PreviewOnboardingViewFactoryConfiguration()), onDismissTap: nil) + ) } +#endif diff --git a/WooCommerce/Classes/POS/Presentation/Payments Onboarding/PointOfSaleCardPresentPaymentOnboardingViewModel.swift b/WooCommerce/Classes/POS/Presentation/Payments Onboarding/PointOfSaleCardPresentPaymentOnboardingViewModel.swift index 90f4c0b8260..51d87b48e85 100644 --- a/WooCommerce/Classes/POS/Presentation/Payments Onboarding/PointOfSaleCardPresentPaymentOnboardingViewModel.swift +++ b/WooCommerce/Classes/POS/Presentation/Payments Onboarding/PointOfSaleCardPresentPaymentOnboardingViewModel.swift @@ -1,16 +1,38 @@ import Foundation +import SwiftUI +import enum Yosemite.CardPresentPaymentOnboardingState + +protocol CardPresentPaymentsOnboardingViewConfiguration: ObservableObject { + var showSupport: (() -> Void)? { get set } + var showURL: ((URL) -> Void)? { get set } + var state: CardPresentPaymentOnboardingState { get } +} + +final class CardPresentPaymentOnboardingViewFactory: ObservableObject, Equatable, Identifiable { + @Published var configuration: any CardPresentPaymentsOnboardingViewConfiguration + @Published var view: any View + + init(configuration: any CardPresentPaymentsOnboardingViewConfiguration, view: any View = EmptyView()) { + self.configuration = configuration + self.view = view + } + + static func == (lhs: CardPresentPaymentOnboardingViewFactory, rhs: CardPresentPaymentOnboardingViewFactory) -> Bool { + lhs.configuration.state == rhs.configuration.state + } +} final class PointOfSaleCardPresentPaymentOnboardingViewModel: ObservableObject { - let onboardingViewModel: CardPresentPaymentsOnboardingViewModel @Published var onboardingURL: URL? + @Published var onboardingViewFactory: CardPresentPaymentOnboardingViewFactory private let onDismissTap: (() -> Void)? - init(onboardingViewModel: CardPresentPaymentsOnboardingViewModel, + init(onboardingViewFactory: CardPresentPaymentOnboardingViewFactory, onDismissTap: (() -> Void)?) { - self.onboardingViewModel = onboardingViewModel + self.onboardingViewFactory = onboardingViewFactory self.onDismissTap = onDismissTap - onboardingViewModel.showURL = { [weak self] url in + self.onboardingViewFactory.configuration.showURL = { [weak self] url in self?.onboardingURL = url } } diff --git a/WooCommerce/Classes/POS/Presentation/PointOfSaleDashboardView.swift b/WooCommerce/Classes/POS/Presentation/PointOfSaleDashboardView.swift index 2ce5982a43f..4710ceaf208 100644 --- a/WooCommerce/Classes/POS/Presentation/PointOfSaleDashboardView.swift +++ b/WooCommerce/Classes/POS/Presentation/PointOfSaleDashboardView.swift @@ -1,10 +1,11 @@ import SwiftUI +import WooFoundation @available(iOS 17.0, *) struct PointOfSaleDashboardView: View { @Environment(PointOfSaleAggregateModel.self) private var posModel @Environment(\.horizontalSizeClass) private var horizontalSizeClass - @Environment(\.posSession) private var session + @Environment(\.posExternalViews) private var externalViews @State private var showExitPOSModal: Bool = false @State private var showSupport: Bool = false @@ -107,10 +108,10 @@ struct PointOfSaleDashboardView: View { .animation(.easeInOut, value: viewState == .loading) .background(Color.posSurface) .navigationBarBackButtonHidden(true) - .posModal(item: $posModel.cardPresentPaymentOnboardingViewModel, onDismiss: { + .posModal(item: $posModel.cardPresentPaymentOnboardingViewFactory, onDismiss: { posModel.cancelCardPaymentsOnboarding() - }) { viewModel in - paymentsOnboardingView(from: viewModel) + }) { factory in + paymentsOnboardingView(from: factory) } .posModal(item: $posModel.cardPresentPaymentAlertViewModel, onDismiss: { @@ -187,16 +188,14 @@ struct PointOfSaleDashboardView: View { private extension PointOfSaleDashboardView { var supportForm: some View { NavigationView { - SupportForm(isPresented: $showSupport, - viewModel: SupportFormViewModel(sourceTag: Constants.supportTag, - defaultSite: session.defaultSite)) - .toolbar { - ToolbarItem(placement: .confirmationAction) { - Button(Localization.supportDone) { - showSupport = false + externalViews.createSupportFormView(isPresented: $showSupport) + .toolbar { + ToolbarItem(placement: .confirmationAction) { + Button(Localization.supportDone) { + showSupport = false + } } } - } } .navigationViewStyle(.stack) } @@ -205,12 +204,13 @@ private extension PointOfSaleDashboardView { SafariView(url: WooConstants.URLs.pointOfSaleDocumentation.asURL()) } - func paymentsOnboardingView(from onboardingViewModel: CardPresentPaymentsOnboardingViewModel) -> some View { - onboardingViewModel.showSupport = { [weak posModel] in + func paymentsOnboardingView(from factory: CardPresentPaymentOnboardingViewFactory) -> some View { + factory.configuration.showSupport = { [weak posModel] in posModel?.cancelCardPaymentsOnboarding() showSupport = true } - return PointOfSaleCardPresentPaymentOnboardingView(viewModel: .init(onboardingViewModel: onboardingViewModel, + + return PointOfSaleCardPresentPaymentOnboardingView(viewModel: .init(onboardingViewFactory: factory, onDismissTap: { posModel.cancelCardPaymentsOnboarding() })) @@ -245,6 +245,8 @@ extension EnvironmentValues { } } + + @available(iOS 17.0, *) private extension PointOfSaleDashboardView { enum Constants { diff --git a/WooCommerce/Classes/POS/Presentation/PointOfSaleEntryPointView.swift b/WooCommerce/Classes/POS/Presentation/PointOfSaleEntryPointView.swift index 192e0c5538d..a0229a7da97 100644 --- a/WooCommerce/Classes/POS/Presentation/PointOfSaleEntryPointView.swift +++ b/WooCommerce/Classes/POS/Presentation/PointOfSaleEntryPointView.swift @@ -1,6 +1,7 @@ import SwiftUI import protocol Yosemite.POSSearchHistoryProviding import protocol Yosemite.PointOfSaleBarcodeScanServiceProtocol +import WooFoundation @available(iOS 17.0, *) struct PointOfSaleEntryPointView: View { @@ -83,8 +84,9 @@ struct PointOfSaleEntryPointView: View { .environment(\.posAnalytics, services.analytics) .environment(\.posCurrencyProvider, services.currency) .environment(\.posFeatureFlags, services.featureFlags) - .environment(\.posSession, services.session) .environment(\.posConnectivityProvider, services.connectivity) + .environment(\.posExternalNavigation, services.externalNavigation) + .environment(\.posExternalViews, services.externalViews) .injectKeyboardObserver() .onAppear { onPointOfSaleModeActiveStateChange(true) diff --git a/WooCommerce/Classes/POS/Presentation/Reusable Views/Buttons/POSButtonProgressViewStyle.swift b/WooCommerce/Classes/POS/Presentation/Reusable Views/Buttons/POSButtonProgressViewStyle.swift index 833427a259a..65518604056 100644 --- a/WooCommerce/Classes/POS/Presentation/Reusable Views/Buttons/POSButtonProgressViewStyle.swift +++ b/WooCommerce/Classes/POS/Presentation/Reusable Views/Buttons/POSButtonProgressViewStyle.swift @@ -1,5 +1,5 @@ import SwiftUI -import WooFoundation +import struct WooFoundation.IndefiniteCircularProgressViewStyle /// A view that displays an animated progress indicator with a circular shape. struct POSButtonProgressViewStyle: ProgressViewStyle { diff --git a/WooCommerce/Classes/POS/Presentation/Reusable Views/Buttons/POSButtonStyle.swift b/WooCommerce/Classes/POS/Presentation/Reusable Views/Buttons/POSButtonStyle.swift index 1d9b1c00418..6e8bb6165e5 100644 --- a/WooCommerce/Classes/POS/Presentation/Reusable Views/Buttons/POSButtonStyle.swift +++ b/WooCommerce/Classes/POS/Presentation/Reusable Views/Buttons/POSButtonStyle.swift @@ -1,4 +1,5 @@ import SwiftUI +import struct WooFoundation.IndefiniteCircularProgressViewStyle /// The size variant of the POS button. enum POSButtonSize { diff --git a/WooCommerce/Classes/POS/Presentation/Reusable Views/POSProgressViewStyle.swift b/WooCommerce/Classes/POS/Presentation/Reusable Views/POSProgressViewStyle.swift index 95ddeb1e500..e0a077147c2 100644 --- a/WooCommerce/Classes/POS/Presentation/Reusable Views/POSProgressViewStyle.swift +++ b/WooCommerce/Classes/POS/Presentation/Reusable Views/POSProgressViewStyle.swift @@ -1,5 +1,5 @@ import SwiftUI -import WooFoundation +import struct WooFoundation.IndefiniteCircularProgressViewStyle struct POSProgressViewStyle: ProgressViewStyle { let size: CGFloat diff --git a/WooCommerce/Classes/POS/Presentation/SimpleProductsOnlyInformation.swift b/WooCommerce/Classes/POS/Presentation/SimpleProductsOnlyInformation.swift index 4a1ab9e817d..0ee62d7a459 100644 --- a/WooCommerce/Classes/POS/Presentation/SimpleProductsOnlyInformation.swift +++ b/WooCommerce/Classes/POS/Presentation/SimpleProductsOnlyInformation.swift @@ -1,14 +1,13 @@ import SwiftUI +import PointOfSale @available(iOS 17.0, *) struct SimpleProductsOnlyInformation: View { @Binding var isPresented: Bool - let deepLinkNavigator: DeepLinkNavigator? + @Environment(\.posExternalNavigation) private var navigation - init(isPresented: Binding, - deepLinkNavigator: DeepLinkNavigator? = AppDelegate.shared.tabBarController) { + init(isPresented: Binding) { self._isPresented = isPresented - self.deepLinkNavigator = deepLinkNavigator } var body: some View { @@ -24,7 +23,7 @@ struct SimpleProductsOnlyInformation: View { Spacer().frame(height: POSSpacing.small) Button { - deepLinkNavigator?.navigate(to: OrdersDestination.createOrder) + navigation.navigateToCreateOrder() } label: { Label(Localization.modalAction, systemImage: "plus") .font(.posBodySmallRegular()) @@ -87,6 +86,5 @@ private extension SimpleProductsOnlyInformation { @available(iOS 17.0, *) #Preview { - SimpleProductsOnlyInformation(isPresented: .constant(true), - deepLinkNavigator: nil) + SimpleProductsOnlyInformation(isPresented: .constant(true)) } diff --git a/WooCommerce/Classes/POS/Presentation/TotalsView.swift b/WooCommerce/Classes/POS/Presentation/TotalsView.swift index 9c62ac402b1..501f5d64a1b 100644 --- a/WooCommerce/Classes/POS/Presentation/TotalsView.swift +++ b/WooCommerce/Classes/POS/Presentation/TotalsView.swift @@ -1,4 +1,5 @@ import SwiftUI +import WooFoundation @available(iOS 17.0, *) struct TotalsView: View { diff --git a/WooCommerce/Classes/POS/TabBar/POSIneligibleView.swift b/WooCommerce/Classes/POS/TabBar/POSIneligibleView.swift index 84fbf0d797e..b1db3c0dda4 100644 --- a/WooCommerce/Classes/POS/TabBar/POSIneligibleView.swift +++ b/WooCommerce/Classes/POS/TabBar/POSIneligibleView.swift @@ -1,4 +1,5 @@ import SwiftUI +import WooFoundation /// A view that displays when the Point of Sale (POS) feature is not available for the current store. /// Shows the specific reason why POS is ineligible and provides a button to re-check eligibility. diff --git a/WooCommerce/Classes/POS/TabBar/POSTabCoordinator.swift b/WooCommerce/Classes/POS/TabBar/POSTabCoordinator.swift index 7e240121520..bcde5854e62 100644 --- a/WooCommerce/Classes/POS/TabBar/POSTabCoordinator.swift +++ b/WooCommerce/Classes/POS/TabBar/POSTabCoordinator.swift @@ -94,10 +94,10 @@ private extension POSTabCoordinator { Task { @MainActor [weak self] in guard let self else { return } let serviceAdaptor = POSServiceLocatorAdaptor() - let collectOrderPaymentAnalyticsTracker = POSCollectOrderPaymentAnalytics(analytics: serviceAdaptor.analytics) + let collectPaymentAnalyticsAdaptor = POSCollectOrderPaymentAnalyticsAdaptor(analytics: serviceAdaptor.analytics) let cardPresentPaymentService = await CardPresentPaymentService(siteID: siteID, stores: storesManager, - collectOrderPaymentAnalyticsTracker: collectOrderPaymentAnalyticsTracker) + collectOrderPaymentAnalyticsTracker: collectPaymentAnalyticsAdaptor) if let receiptService = POSReceiptService(siteID: siteID, credentials: credentials), let orderService = POSOrderService(siteID: siteID, @@ -132,7 +132,7 @@ private extension POSTabCoordinator { analytics: serviceAdaptor.analytics, featureFlagService: serviceAdaptor.featureFlags, pluginsService: PluginsService(storageManager: storageManager)), - collectOrderPaymentAnalyticsTracker: collectOrderPaymentAnalyticsTracker, + collectOrderPaymentAnalyticsTracker: collectPaymentAnalyticsAdaptor, searchHistoryService: POSSearchHistoryService(siteID: siteID), popularPurchasableItemsController: PointOfSaleItemsController( itemProvider: PointOfSaleItemService(currencySettings: currencySettings), diff --git a/WooCommerce/Classes/POS/Utils/PreviewHelpers.swift b/WooCommerce/Classes/POS/Utils/PreviewHelpers.swift index 2f6e0ed1c67..3031e81239e 100644 --- a/WooCommerce/Classes/POS/Utils/PreviewHelpers.swift +++ b/WooCommerce/Classes/POS/Utils/PreviewHelpers.swift @@ -27,6 +27,7 @@ import struct Yosemite.PaymentIntent import protocol Yosemite.Action import struct Yosemite.Site import PointOfSale +import SwiftUI // MARK: - PreviewProvider helpers // @@ -232,7 +233,7 @@ struct POSPreviewHelpers { couponsSearchController: couponsSearchController, cardPresentPaymentService: cardPresentPaymentService, orderController: orderController, - analytics: POSPreviewAnalytics(), + analytics: EmptyPOSAnalytics(), collectOrderPaymentAnalyticsTracker: collectOrderPaymentAnalyticsTracker, searchHistoryService: searchHistoryService, popularPurchasableItemsController: popularItemsController, @@ -286,18 +287,12 @@ final class POSCollectOrderPaymentPreviewAnalytics: POSCollectOrderPaymentAnalyt func trackReceiptPrintFailed(error: any Error) {} } -final class POSPreviewAnalytics: POSAnalyticsProviding { - func track(event: WooFoundationCore.WooAnalyticsEvent) {} - func track(_ stat: WooFoundationCore.WooAnalyticsStat, parameters: [String: any WooFoundationCore.WooAnalyticsEventPropertyType]) {} - func track(_ stat: WooFoundationCore.WooAnalyticsStat) {} - func track(_ stat: WooAnalyticsStat, parameters: [String: WooAnalyticsEventPropertyType] = [:], error: Error) {} -} - final class POSPreviewServices: POSDependencyProviding { var analytics: POSAnalyticsProviding = EmptyPOSAnalytics() var currency: POSCurrencySettingsProviding = EmptyPOSCurrencySettings() var featureFlags: POSFeatureFlagProviding = EmptyPOSFeatureFlags() - var session: POSSessionManagerProviding = EmptyPOSSessionManager() var connectivity: POSConnectivityProviding = EmptyPOSConnectivityProvider() + var externalNavigation: POSExternalNavigationProviding = EmptyPOSExternalNavigation() + var externalViews: POSExternalViewProviding = EmptyPOSExternalView() } #endif diff --git a/WooCommerce/Classes/POS/ViewHelpers/CartViewHelper.swift b/WooCommerce/Classes/POS/ViewHelpers/CartViewHelper.swift index dcca305c839..df5b2a89f81 100644 --- a/WooCommerce/Classes/POS/ViewHelpers/CartViewHelper.swift +++ b/WooCommerce/Classes/POS/ViewHelpers/CartViewHelper.swift @@ -1,4 +1,5 @@ import Foundation +import WooFoundation struct CartViewHelper { func itemsInCartLabel(for itemsCount: Int) -> String? { diff --git a/WooCommerce/Classes/POS/ViewHelpers/TotalsViewHelper.swift b/WooCommerce/Classes/POS/ViewHelpers/TotalsViewHelper.swift index 9f1d5f896e7..25243a4c9ce 100644 --- a/WooCommerce/Classes/POS/ViewHelpers/TotalsViewHelper.swift +++ b/WooCommerce/Classes/POS/ViewHelpers/TotalsViewHelper.swift @@ -1,4 +1,5 @@ import Foundation +import WooFoundation struct TotalsViewHelper { func shouldShowTotalsFields(for paymentState: PointOfSalePaymentState) -> Bool { diff --git a/WooCommerce/Classes/Tools/CardPresentPluginsDataProvider.swift b/WooCommerce/Classes/Tools/CardPresentPluginsDataProvider.swift index 694dda1fa47..16b30c50a82 100644 --- a/WooCommerce/Classes/Tools/CardPresentPluginsDataProvider.swift +++ b/WooCommerce/Classes/Tools/CardPresentPluginsDataProvider.swift @@ -1,6 +1,7 @@ import Yosemite import Foundation import Storage +import class WooFoundation.VersionHelpers /// Provides information about which of the payment plugins (WCPay and Stripe) are installed and active /// diff --git a/WooCommerce/Classes/ViewModels/CardPresentPayments/PaymentReceiptEmailParameterDeterminer.swift b/WooCommerce/Classes/ViewModels/CardPresentPayments/PaymentReceiptEmailParameterDeterminer.swift index d4f6229beaa..58de08ea8b4 100644 --- a/WooCommerce/Classes/ViewModels/CardPresentPayments/PaymentReceiptEmailParameterDeterminer.swift +++ b/WooCommerce/Classes/ViewModels/CardPresentPayments/PaymentReceiptEmailParameterDeterminer.swift @@ -1,5 +1,6 @@ import Foundation import Yosemite +import class WooFoundation.VersionHelpers /// Determines the email to be set (if any) on a receipt /// diff --git a/WooCommerce/Classes/ViewModels/Order Details/CardPresentPaymentsReadinessUseCase.swift b/WooCommerce/Classes/ViewModels/Order Details/CardPresentPaymentsReadinessUseCase.swift index c9e6dd90028..44c0a5d2142 100644 --- a/WooCommerce/Classes/ViewModels/Order Details/CardPresentPaymentsReadinessUseCase.swift +++ b/WooCommerce/Classes/ViewModels/Order Details/CardPresentPaymentsReadinessUseCase.swift @@ -1,6 +1,7 @@ import Foundation import Combine import Yosemite +import WooFoundation final class CardPresentPaymentsReadinessUseCase { /// Represents the system's readiness to accept a card payment diff --git a/WooCommerce/Classes/ViewModels/Order Details/OrderDetailsShipmentDetailsView.swift b/WooCommerce/Classes/ViewModels/Order Details/OrderDetailsShipmentDetailsView.swift index b4f880e55b0..e41e0980de0 100644 --- a/WooCommerce/Classes/ViewModels/Order Details/OrderDetailsShipmentDetailsView.swift +++ b/WooCommerce/Classes/ViewModels/Order Details/OrderDetailsShipmentDetailsView.swift @@ -1,5 +1,6 @@ import SwiftUI import Yosemite +import WooFoundation struct OrderDetailsShipmentDetailsView: View { let shipment: WooShippingShipment diff --git a/WooCommerce/Classes/ViewModels/Order Details/Receipts/ReceiptEligibilityUseCase.swift b/WooCommerce/Classes/ViewModels/Order Details/Receipts/ReceiptEligibilityUseCase.swift index c7a21e56f89..0f10bae3f17 100644 --- a/WooCommerce/Classes/ViewModels/Order Details/Receipts/ReceiptEligibilityUseCase.swift +++ b/WooCommerce/Classes/ViewModels/Order Details/Receipts/ReceiptEligibilityUseCase.swift @@ -1,5 +1,6 @@ import Yosemite import Experiments +import class WooFoundation.VersionHelpers protocol ReceiptEligibilityUseCaseProtocol { func isEligibleForBackendReceipts(onCompletion: @escaping (Bool) -> Void) diff --git a/WooCommerce/Classes/ViewRelated/Authentication/AuthenticationFormFieldView.swift b/WooCommerce/Classes/ViewRelated/Authentication/AuthenticationFormFieldView.swift index b183144c9e8..7fb0a470f57 100644 --- a/WooCommerce/Classes/ViewRelated/Authentication/AuthenticationFormFieldView.swift +++ b/WooCommerce/Classes/ViewRelated/Authentication/AuthenticationFormFieldView.swift @@ -1,4 +1,5 @@ import SwiftUI +import struct WooFoundation.WooRoundedBorderTextFieldStyle /// Necessary data for the account creation / authentication form field. struct AuthenticationFormFieldViewModel { diff --git a/WooCommerce/Classes/ViewRelated/Blaze/BudgetSetting/BlazeBudgetSettingView.swift b/WooCommerce/Classes/ViewRelated/Blaze/BudgetSetting/BlazeBudgetSettingView.swift index cef6ad7ca80..be631280051 100644 --- a/WooCommerce/Classes/ViewRelated/Blaze/BudgetSetting/BlazeBudgetSettingView.swift +++ b/WooCommerce/Classes/ViewRelated/Blaze/BudgetSetting/BlazeBudgetSettingView.swift @@ -1,4 +1,5 @@ import SwiftUI +import struct WooFoundation.ScrollableVStack /// View to set budget for a new Blaze campaign struct BlazeBudgetSettingView: View { diff --git a/WooCommerce/Classes/ViewRelated/Blaze/BudgetSetting/BlazeScheduleSettingView.swift b/WooCommerce/Classes/ViewRelated/Blaze/BudgetSetting/BlazeScheduleSettingView.swift index 7b3d9a627db..1c1b302a555 100644 --- a/WooCommerce/Classes/ViewRelated/Blaze/BudgetSetting/BlazeScheduleSettingView.swift +++ b/WooCommerce/Classes/ViewRelated/Blaze/BudgetSetting/BlazeScheduleSettingView.swift @@ -1,4 +1,5 @@ import SwiftUI +import struct WooFoundation.ScrollableVStack /// View to set the schedule for a Blaze campaign. /// diff --git a/WooCommerce/Classes/ViewRelated/Blaze/CampaignCreation/BlazeCampaignCreationLoadingView.swift b/WooCommerce/Classes/ViewRelated/Blaze/CampaignCreation/BlazeCampaignCreationLoadingView.swift index 76275a89454..110729dff04 100644 --- a/WooCommerce/Classes/ViewRelated/Blaze/CampaignCreation/BlazeCampaignCreationLoadingView.swift +++ b/WooCommerce/Classes/ViewRelated/Blaze/CampaignCreation/BlazeCampaignCreationLoadingView.swift @@ -1,4 +1,5 @@ import SwiftUI +import struct WooFoundation.ScrollableVStack struct BlazeCampaignCreationLoadingView: View { var body: some View { diff --git a/WooCommerce/Classes/ViewRelated/CardPresentPayments/CardPresentPaymentsModalViewController.swift b/WooCommerce/Classes/ViewRelated/CardPresentPayments/CardPresentPaymentsModalViewController.swift index 13ec14409e7..6e41681e700 100644 --- a/WooCommerce/Classes/ViewRelated/CardPresentPayments/CardPresentPaymentsModalViewController.swift +++ b/WooCommerce/Classes/ViewRelated/CardPresentPayments/CardPresentPaymentsModalViewController.swift @@ -1,6 +1,7 @@ import UIKit import SwiftUI import SafariServices +import struct WooFoundation.IndefiniteCircularProgressViewStyle /// UI containing modals presented in the Card Present Payments flows. final class CardPresentPaymentsModalViewController: UIViewController, CardReaderModalFlowViewControllerProtocol { diff --git a/WooCommerce/Classes/ViewRelated/Coupons/CouponDetails/CouponDetails.swift b/WooCommerce/Classes/ViewRelated/Coupons/CouponDetails/CouponDetails.swift index 168d1f55996..f0aa5663f48 100644 --- a/WooCommerce/Classes/ViewRelated/Coupons/CouponDetails/CouponDetails.swift +++ b/WooCommerce/Classes/ViewRelated/Coupons/CouponDetails/CouponDetails.swift @@ -1,5 +1,6 @@ import SwiftUI import Yosemite +import WooFoundation /// Hosting controller wrapper for `CouponDetails` /// diff --git a/WooCommerce/Classes/ViewRelated/Customers/CustomersListViewModel.swift b/WooCommerce/Classes/ViewRelated/Customers/CustomersListViewModel.swift index c284bd7b043..a5f05b61e98 100644 --- a/WooCommerce/Classes/ViewRelated/Customers/CustomersListViewModel.swift +++ b/WooCommerce/Classes/ViewRelated/Customers/CustomersListViewModel.swift @@ -2,6 +2,7 @@ import Foundation import Yosemite import protocol Storage.StorageManagerType import Combine +import class WooFoundation.VersionHelpers final class CustomersListViewModel: ObservableObject { diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/ProductStock/ProductStockDashboardCard.swift b/WooCommerce/Classes/ViewRelated/Dashboard/ProductStock/ProductStockDashboardCard.swift index 29a7b82b37a..18f90d21809 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/ProductStock/ProductStockDashboardCard.swift +++ b/WooCommerce/Classes/ViewRelated/Dashboard/ProductStock/ProductStockDashboardCard.swift @@ -2,6 +2,7 @@ import Kingfisher import SwiftUI import struct Yosemite.ProductReport import struct Yosemite.DashboardCard +import WooFoundation /// View for displaying stock based on status on the dashboard. /// diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/CardReadersV2/SetUpTapToPayCompleteViewController.swift b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/CardReadersV2/SetUpTapToPayCompleteViewController.swift index a697c65fee3..8d2bd98a9d9 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/CardReadersV2/SetUpTapToPayCompleteViewController.swift +++ b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/CardReadersV2/SetUpTapToPayCompleteViewController.swift @@ -1,4 +1,5 @@ import SwiftUI +import struct WooFoundation.ScrollableVStack /// This view controller is used when no reader is connected. It assists /// the merchant in connecting to a reader. diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/CardReadersV2/SetUpTapToPayTryPaymentPromptViewController.swift b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/CardReadersV2/SetUpTapToPayTryPaymentPromptViewController.swift index ea51aecd575..4a3cc35ddaa 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/CardReadersV2/SetUpTapToPayTryPaymentPromptViewController.swift +++ b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/CardReadersV2/SetUpTapToPayTryPaymentPromptViewController.swift @@ -1,4 +1,5 @@ import SwiftUI +import struct WooFoundation.ScrollableVStack /// This view controller is used when no reader is connected. It assists /// the merchant in connecting to a reader. diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/CardReadersV2/Tap to Pay Education/TapToPayEducationStepView.swift b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/CardReadersV2/Tap to Pay Education/TapToPayEducationStepView.swift index 29eb983141c..204654fac2b 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/CardReadersV2/Tap to Pay Education/TapToPayEducationStepView.swift +++ b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/CardReadersV2/Tap to Pay Education/TapToPayEducationStepView.swift @@ -1,5 +1,6 @@ import Foundation import SwiftUI +import struct WooFoundation.ScrollableVStack struct TapToPayEducationStepView: View { private let viewModel: TapToPayEducationStepViewModel diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/In-Person Payments/InPersonPaymentsCompletedView.swift b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/In-Person Payments/InPersonPaymentsCompletedView.swift index 341be53efb5..1f53c302328 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/In-Person Payments/InPersonPaymentsCompletedView.swift +++ b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/In-Person Payments/InPersonPaymentsCompletedView.swift @@ -1,4 +1,5 @@ import SwiftUI +import struct WooFoundation.ScrollableVStack struct InPersonPaymentsCompleted: View { var body: some View { diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/In-Person Payments/InPersonPaymentsLoadingView.swift b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/In-Person Payments/InPersonPaymentsLoadingView.swift index 2ef83ccbe3e..5b7cec2ff47 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/In-Person Payments/InPersonPaymentsLoadingView.swift +++ b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/In-Person Payments/InPersonPaymentsLoadingView.swift @@ -1,4 +1,5 @@ import SwiftUI +import struct WooFoundation.ScrollableVStack struct InPersonPaymentsLoading: View { var body: some View { diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/In-Person Payments/InPersonPaymentsSelectPluginView.swift b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/In-Person Payments/InPersonPaymentsSelectPluginView.swift index c3149d8dd65..27381027bcf 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/In-Person Payments/InPersonPaymentsSelectPluginView.swift +++ b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/In-Person Payments/InPersonPaymentsSelectPluginView.swift @@ -1,5 +1,6 @@ import SwiftUI import Yosemite +import struct WooFoundation.ScrollableVStack struct InPersonPaymentsSelectPluginRow: View { let icon: UIImage diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/In-Person Payments/Onboarding Errors/InPersonPaymentsCashOnDeliveryPaymentGatewayNotSetUpView.swift b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/In-Person Payments/Onboarding Errors/InPersonPaymentsCashOnDeliveryPaymentGatewayNotSetUpView.swift index 5a1e7d08102..848546a26e9 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/In-Person Payments/Onboarding Errors/InPersonPaymentsCashOnDeliveryPaymentGatewayNotSetUpView.swift +++ b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/In-Person Payments/Onboarding Errors/InPersonPaymentsCashOnDeliveryPaymentGatewayNotSetUpView.swift @@ -1,5 +1,6 @@ import SwiftUI import Yosemite +import struct WooFoundation.ScrollableVStack struct InPersonPaymentsCashOnDeliveryPaymentGatewayNotSetUpView: View { @ObservedObject var viewModel: InPersonPaymentsCashOnDeliveryPaymentGatewayNotSetUpViewModel diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/In-Person Payments/Onboarding Errors/InPersonPaymentsOnboardingError.swift b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/In-Person Payments/Onboarding Errors/InPersonPaymentsOnboardingError.swift index 0bd05cfb6ce..acdd7206277 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/In-Person Payments/Onboarding Errors/InPersonPaymentsOnboardingError.swift +++ b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/In-Person Payments/Onboarding Errors/InPersonPaymentsOnboardingError.swift @@ -1,5 +1,6 @@ import SwiftUI import Yosemite +import struct WooFoundation.ScrollableVStack struct InPersonPaymentsOnboardingError: View { let title: String diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/In-Person Payments/Onboarding Errors/InPersonPaymentsPluginNotSetup.swift b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/In-Person Payments/Onboarding Errors/InPersonPaymentsPluginNotSetup.swift index def4eccd282..169e7e62234 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/In-Person Payments/Onboarding Errors/InPersonPaymentsPluginNotSetup.swift +++ b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/In-Person Payments/Onboarding Errors/InPersonPaymentsPluginNotSetup.swift @@ -1,5 +1,6 @@ import SwiftUI import Yosemite +import struct WooFoundation.ScrollableVStack struct InPersonPaymentsPluginNotSetup: View { let plugin: CardPresentPaymentsPlugin diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/In-Person Payments/SafariView.swift b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/In-Person Payments/SafariView.swift deleted file mode 100644 index a06f630aed0..00000000000 --- a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/In-Person Payments/SafariView.swift +++ /dev/null @@ -1,19 +0,0 @@ -import SwiftUI -import SafariServices - -/// SwiftUI interface for UIKit SFSafariViewController -/// Provides a visible interface for web browsing, and Safari features -/// -struct SafariView: UIViewControllerRepresentable { - - let url: URL - - func makeUIViewController(context: UIViewControllerRepresentableContext) -> SFSafariViewController { - return SFSafariViewController(url: url) - } - - func updateUIViewController(_ uiViewController: SFSafariViewController, - context: UIViewControllerRepresentableContext) { - - } -} diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/LegacyPOSTabEligibilityChecker.swift b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/LegacyPOSTabEligibilityChecker.swift index b23b557752d..f036d1837fc 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/LegacyPOSTabEligibilityChecker.swift +++ b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/LegacyPOSTabEligibilityChecker.swift @@ -3,6 +3,7 @@ import UIKit import class WooFoundation.CurrencySettings import enum WooFoundation.CountryCode import enum WooFoundation.CurrencyCode +import class WooFoundation.VersionHelpers import protocol Experiments.FeatureFlagService import struct Yosemite.SiteSetting import protocol Yosemite.POSEligibilityServiceProtocol diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/POSTabEligibilityChecker.swift b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/POSTabEligibilityChecker.swift index fe272c12908..0d2a341c882 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/POSTabEligibilityChecker.swift +++ b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/POSTabEligibilityChecker.swift @@ -3,6 +3,7 @@ import UIKit import class WooFoundation.CurrencySettings import enum WooFoundation.CountryCode import enum WooFoundation.CurrencyCode +import class WooFoundation.VersionHelpers import protocol Experiments.FeatureFlagService import struct Yosemite.SiteSetting import protocol Yosemite.POSEligibilityServiceProtocol diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/PluginDetailsRowView.swift b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/PluginDetailsRowView.swift index 5083504203e..71ec9c7d82e 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/PluginDetailsRowView.swift +++ b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/PluginDetailsRowView.swift @@ -1,5 +1,6 @@ import SwiftUI import Yosemite +import WooFoundation struct PluginListView: View { private let siteID: Int64 diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/Plugins/PluginDetailsViewModel.swift b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/Plugins/PluginDetailsViewModel.swift index fdb7788dbad..bae2b41f136 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/Plugins/PluginDetailsViewModel.swift +++ b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/Plugins/PluginDetailsViewModel.swift @@ -1,6 +1,7 @@ import Foundation import Yosemite import protocol Storage.StorageManagerType +import class WooFoundation.VersionHelpers final class PluginDetailsViewModel: ObservableObject { /// ID of the site to load plugins for diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/Settings/SettingsViewModel.swift b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/Settings/SettingsViewModel.swift index fd16a6d874d..c85d6953834 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/Settings/SettingsViewModel.swift +++ b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/Settings/SettingsViewModel.swift @@ -4,6 +4,7 @@ import Storage import class Networking.UserAgent import Experiments import protocol WooFoundation.Analytics +import class WooFoundation.VersionHelpers protocol SettingsViewModelOutput { typealias Section = SettingsViewController.Section diff --git a/WooCommerce/Classes/ViewRelated/JetpackSetup/AdminRole/AdminRoleRequiredView.swift b/WooCommerce/Classes/ViewRelated/JetpackSetup/AdminRole/AdminRoleRequiredView.swift index 61c63ff6344..a6e7183e9cd 100644 --- a/WooCommerce/Classes/ViewRelated/JetpackSetup/AdminRole/AdminRoleRequiredView.swift +++ b/WooCommerce/Classes/ViewRelated/JetpackSetup/AdminRole/AdminRoleRequiredView.swift @@ -1,4 +1,5 @@ import SwiftUI +import struct WooFoundation.ScrollableVStack /// Hosting controller that wraps the `AdminRoleRequiredView`. final class AdminRoleRequiredHostingController: UIHostingController { diff --git a/WooCommerce/Classes/ViewRelated/Orders/Order Creation/CustomerSection/CustomerCard/CollapsibleCustomerCard.swift b/WooCommerce/Classes/ViewRelated/Orders/Order Creation/CustomerSection/CustomerCard/CollapsibleCustomerCard.swift index 672b94ba82a..e70fbd98b69 100644 --- a/WooCommerce/Classes/ViewRelated/Orders/Order Creation/CustomerSection/CustomerCard/CollapsibleCustomerCard.swift +++ b/WooCommerce/Classes/ViewRelated/Orders/Order Creation/CustomerSection/CustomerCard/CollapsibleCustomerCard.swift @@ -1,4 +1,5 @@ import SwiftUI +import struct WooFoundation.WooRoundedBorderTextFieldStyle /// Displays a collapsible customer card that shows customer details in the collapsed and expanded states. struct CollapsibleCustomerCard: View { diff --git a/WooCommerce/Classes/ViewRelated/Orders/Order Creation/CustomerSection/CustomerSelectorViewModel.swift b/WooCommerce/Classes/ViewRelated/Orders/Order Creation/CustomerSection/CustomerSelectorViewModel.swift index 68ef00f5fca..9a68b138413 100644 --- a/WooCommerce/Classes/ViewRelated/Orders/Order Creation/CustomerSection/CustomerSelectorViewModel.swift +++ b/WooCommerce/Classes/ViewRelated/Orders/Order Creation/CustomerSection/CustomerSelectorViewModel.swift @@ -1,5 +1,6 @@ import Foundation import Yosemite +import class WooFoundation.VersionHelpers final class CustomerSelectorViewModel { private let stores: StoresManager diff --git a/WooCommerce/Classes/ViewRelated/Orders/Order Creation/PaymentSection/GiftCardInputView.swift b/WooCommerce/Classes/ViewRelated/Orders/Order Creation/PaymentSection/GiftCardInputView.swift index d370b6b0037..110a8558f92 100644 --- a/WooCommerce/Classes/ViewRelated/Orders/Order Creation/PaymentSection/GiftCardInputView.swift +++ b/WooCommerce/Classes/ViewRelated/Orders/Order Creation/PaymentSection/GiftCardInputView.swift @@ -1,4 +1,5 @@ import SwiftUI +import struct WooFoundation.WooRoundedBorderTextFieldStyle /// Allows the user to enter a gift card code. struct GiftCardInputView: View { diff --git a/WooCommerce/Classes/ViewRelated/Orders/Order Details/Product List Section/Product Details/AggregatedProductListViewController.swift b/WooCommerce/Classes/ViewRelated/Orders/Order Details/Product List Section/Product Details/AggregatedProductListViewController.swift index 93526cf01bb..b4052b596f7 100644 --- a/WooCommerce/Classes/ViewRelated/Orders/Order Details/Product List Section/Product Details/AggregatedProductListViewController.swift +++ b/WooCommerce/Classes/ViewRelated/Orders/Order Details/Product List Section/Product Details/AggregatedProductListViewController.swift @@ -1,5 +1,6 @@ import UIKit import Yosemite +import WooFoundation /// A simple Product List presented from the Order Details screen -> Shipping Labels Packages. diff --git a/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/Refund/WooShippingRefundView.swift b/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/Refund/WooShippingRefundView.swift index b9532b06fc7..831cd10603f 100644 --- a/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/Refund/WooShippingRefundView.swift +++ b/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/Refund/WooShippingRefundView.swift @@ -1,5 +1,6 @@ import SwiftUI import Yosemite +import struct WooFoundation.ScrollableVStack /// View for requesting refund for a shipping label. /// diff --git a/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/UPSTOS/UPSTermsView.swift b/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/UPSTOS/UPSTermsView.swift index 220a448cc2c..90ac02efcee 100644 --- a/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/UPSTOS/UPSTermsView.swift +++ b/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/UPSTOS/UPSTermsView.swift @@ -1,4 +1,5 @@ import SwiftUI +import struct WooFoundation.ScrollableVStack /// View for reviewing UPS Terms and Conditions. struct UPSTermsView: View { diff --git a/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShipping Split Shipments/WooShippingSplitShipmentsView.swift b/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShipping Split Shipments/WooShippingSplitShipmentsView.swift index 18dfc2fb714..5408c07e07d 100644 --- a/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShipping Split Shipments/WooShippingSplitShipmentsView.swift +++ b/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShipping Split Shipments/WooShippingSplitShipmentsView.swift @@ -1,5 +1,6 @@ import SwiftUI import Yosemite +import struct WooFoundation.ScrollableVStack struct WooShippingSplitShipmentsView: View { @Environment(\.dismiss) private var dismiss diff --git a/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShippingPaymentMethod/WooShippingPaymentMethodsView.swift b/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShippingPaymentMethod/WooShippingPaymentMethodsView.swift index 555e5f594a9..e2c40870087 100644 --- a/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShippingPaymentMethod/WooShippingPaymentMethodsView.swift +++ b/WooCommerce/Classes/ViewRelated/Orders/Order Details/Shipping Labels/WooShipping Create Shipping Labels/WooShippingPaymentMethod/WooShippingPaymentMethodsView.swift @@ -1,6 +1,7 @@ import SwiftUI import struct Yosemite.ShippingLabelPaymentMethod import struct Yosemite.ShippingLabelAccountSettings +import struct WooFoundation.ScrollableVStack struct WooShippingPaymentMethodsView: View { diff --git a/WooCommerce/Classes/ViewRelated/Orders/OrderListViewController+Activity.swift b/WooCommerce/Classes/ViewRelated/Orders/OrderListViewController+Activity.swift index bd0984307c3..0642418ccac 100644 --- a/WooCommerce/Classes/ViewRelated/Orders/OrderListViewController+Activity.swift +++ b/WooCommerce/Classes/ViewRelated/Orders/OrderListViewController+Activity.swift @@ -1,4 +1,5 @@ import Foundation +import WooFoundation // MARK: - SearchableActivity Conformance extension OrderListViewController: SearchableActivityConvertible { diff --git a/WooCommerce/Classes/ViewRelated/Products/AI/ProductSharingMessageGenerationView.swift b/WooCommerce/Classes/ViewRelated/Products/AI/ProductSharingMessageGenerationView.swift index bdcda6a08b1..62ae7bb728a 100644 --- a/WooCommerce/Classes/ViewRelated/Products/AI/ProductSharingMessageGenerationView.swift +++ b/WooCommerce/Classes/ViewRelated/Products/AI/ProductSharingMessageGenerationView.swift @@ -1,5 +1,6 @@ import SwiftUI import struct Yosemite.Product +import struct WooFoundation.ScrollableVStack /// Hosting controller for `ProductSharingMessageGenerationView`. final class ProductSharingMessageGenerationHostingController: UIHostingController { diff --git a/WooCommerce/Classes/ViewRelated/Products/Add Product/AddProductWithAI/Preview/ProductDetailPreviewView.swift b/WooCommerce/Classes/ViewRelated/Products/Add Product/AddProductWithAI/Preview/ProductDetailPreviewView.swift index 652d5dec3a7..e0a9685320d 100644 --- a/WooCommerce/Classes/ViewRelated/Products/Add Product/AddProductWithAI/Preview/ProductDetailPreviewView.swift +++ b/WooCommerce/Classes/ViewRelated/Products/Add Product/AddProductWithAI/Preview/ProductDetailPreviewView.swift @@ -1,4 +1,5 @@ import SwiftUI +import WooFoundation /// View for previewing product details generated with AI. /// diff --git a/WooCommerce/Classes/ViewRelated/Products/Add Product/FirstProductCreated/FirstProductCreatedView.swift b/WooCommerce/Classes/ViewRelated/Products/Add Product/FirstProductCreated/FirstProductCreatedView.swift index ba718ef6fd5..7cede21f8cd 100644 --- a/WooCommerce/Classes/ViewRelated/Products/Add Product/FirstProductCreated/FirstProductCreatedView.swift +++ b/WooCommerce/Classes/ViewRelated/Products/Add Product/FirstProductCreated/FirstProductCreatedView.swift @@ -1,6 +1,7 @@ import ConfettiSwiftUI import SwiftUI import struct Yosemite.Product +import struct WooFoundation.ScrollableVStack final class FirstProductCreatedHostingController: UIHostingController { /// The coordinator for sharing products diff --git a/WooCommerce/Classes/ViewRelated/Products/Categories/Selector/ProductCategorySelector.swift b/WooCommerce/Classes/ViewRelated/Products/Categories/Selector/ProductCategorySelector.swift index 65aac744292..3837ebf613b 100644 --- a/WooCommerce/Classes/ViewRelated/Products/Categories/Selector/ProductCategorySelector.swift +++ b/WooCommerce/Classes/ViewRelated/Products/Categories/Selector/ProductCategorySelector.swift @@ -1,4 +1,5 @@ import SwiftUI +import WooFoundation /// View showing a list of product categories to select from. /// diff --git a/WooCommerce/Classes/ViewRelated/Products/Edit Product/Product Settings/ProductPasswordEligibilityUseCase.swift b/WooCommerce/Classes/ViewRelated/Products/Edit Product/Product Settings/ProductPasswordEligibilityUseCase.swift index 855a75ffab3..4077b6fbdd7 100644 --- a/WooCommerce/Classes/ViewRelated/Products/Edit Product/Product Settings/ProductPasswordEligibilityUseCase.swift +++ b/WooCommerce/Classes/ViewRelated/Products/Edit Product/Product Settings/ProductPasswordEligibilityUseCase.swift @@ -1,5 +1,6 @@ import Yosemite import Storage +import class WooFoundation.VersionHelpers final class ProductPasswordEligibilityUseCase { private let stores: StoresManager diff --git a/WooCommerce/Classes/ViewRelated/Products/View Models/ProductsTabProductViewModel.swift b/WooCommerce/Classes/ViewRelated/Products/View Models/ProductsTabProductViewModel.swift index a44042fdb2d..42ff472cb1d 100644 --- a/WooCommerce/Classes/ViewRelated/Products/View Models/ProductsTabProductViewModel.swift +++ b/WooCommerce/Classes/ViewRelated/Products/View Models/ProductsTabProductViewModel.swift @@ -1,6 +1,7 @@ import Foundation import UIKit import Yosemite +import WooFoundation private extension ProductStatus { var descriptionColor: UIColor { diff --git a/WooCommerce/Classes/ViewRelated/ReusableViews/SwiftUI Components/CelebrationView.swift b/WooCommerce/Classes/ViewRelated/ReusableViews/SwiftUI Components/CelebrationView.swift index 09a088362e5..3ddba714c2e 100644 --- a/WooCommerce/Classes/ViewRelated/ReusableViews/SwiftUI Components/CelebrationView.swift +++ b/WooCommerce/Classes/ViewRelated/ReusableViews/SwiftUI Components/CelebrationView.swift @@ -1,4 +1,5 @@ import SwiftUI +import struct WooFoundation.ScrollableVStack /// Hosting controller for `CelebrationView`. /// diff --git a/WooCommerce/Classes/ViewRelated/ReusableViews/SwiftUI Components/ExpandableBottomSheet.swift b/WooCommerce/Classes/ViewRelated/ReusableViews/SwiftUI Components/ExpandableBottomSheet.swift index 7366a6c5988..ba9608e1cac 100644 --- a/WooCommerce/Classes/ViewRelated/ReusableViews/SwiftUI Components/ExpandableBottomSheet.swift +++ b/WooCommerce/Classes/ViewRelated/ReusableViews/SwiftUI Components/ExpandableBottomSheet.swift @@ -209,26 +209,3 @@ struct ExpandableBottomSheet_Previews: PreviewProvider { } } - -struct SizeTracker: ViewModifier { - @Binding var size: CGSize - - func body(content: Content) -> some View { - content - .background(GeometryReader { proxy in - Color.clear - .onAppear { - self.size = proxy.size - } - .onChange(of: proxy.size) { newSize in - self.size = newSize - } - }) - } -} - -extension View { - func trackSize(size: Binding) -> some View { - modifier(SizeTracker(size: size)) - } -} diff --git a/WooCommerce/Classes/ViewRelated/Upgrades/CurrentPlanDetailsView.swift b/WooCommerce/Classes/ViewRelated/Upgrades/CurrentPlanDetailsView.swift index bb443539eea..83c27914d70 100644 --- a/WooCommerce/Classes/ViewRelated/Upgrades/CurrentPlanDetailsView.swift +++ b/WooCommerce/Classes/ViewRelated/Upgrades/CurrentPlanDetailsView.swift @@ -1,4 +1,5 @@ import SwiftUI +import WooFoundation struct CurrentPlanDetailsView: View { @State var expirationDate: String? diff --git a/WooCommerce/Classes/ViewRelated/Upgrades/UpgradeWaitingView.swift b/WooCommerce/Classes/ViewRelated/Upgrades/UpgradeWaitingView.swift index f759ee040ff..a769a88c122 100644 --- a/WooCommerce/Classes/ViewRelated/Upgrades/UpgradeWaitingView.swift +++ b/WooCommerce/Classes/ViewRelated/Upgrades/UpgradeWaitingView.swift @@ -1,4 +1,5 @@ import SwiftUI +import struct WooFoundation.IndefiniteCircularProgressViewStyle struct UpgradeWaitingView: View { let planName: String diff --git a/WooCommerce/Woo Watch App/Orders/OrderDetailView.swift b/WooCommerce/Woo Watch App/Orders/OrderDetailView.swift index 88284a617b1..0f9556f3d16 100644 --- a/WooCommerce/Woo Watch App/Orders/OrderDetailView.swift +++ b/WooCommerce/Woo Watch App/Orders/OrderDetailView.swift @@ -1,4 +1,5 @@ import SwiftUI +import WooFoundationCore /// View for the order detail /// diff --git a/WooCommerce/WooCommerce.xcodeproj/project.pbxproj b/WooCommerce/WooCommerce.xcodeproj/project.pbxproj index 353a2bb7d7d..d76c154eb95 100644 --- a/WooCommerce/WooCommerce.xcodeproj/project.pbxproj +++ b/WooCommerce/WooCommerce.xcodeproj/project.pbxproj @@ -96,6 +96,7 @@ 01BD774A2C58D29700147191 /* PointOfSaleCardPresentPaymentDisconnectedMessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01BD77492C58D29700147191 /* PointOfSaleCardPresentPaymentDisconnectedMessageView.swift */; }; 01BD774C2C58D2BE00147191 /* PointOfSaleCardPresentPaymentDisconnectedMessageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01BD774B2C58D2BE00147191 /* PointOfSaleCardPresentPaymentDisconnectedMessageViewModel.swift */; }; 01BE94042DDCC7670063541C /* PointOfSaleEmptyErrorStateViewLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01BE94032DDCC7650063541C /* PointOfSaleEmptyErrorStateViewLayout.swift */; }; + 01C230E92E3A334D00621DB0 /* MockOnboardingViewFactoryConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01C230E82E3A334A00621DB0 /* MockOnboardingViewFactoryConfiguration.swift */; }; 01C9C59F2DA3D98400CD81D8 /* CartRowRemoveButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01C9C59E2DA3D97E00CD81D8 /* CartRowRemoveButton.swift */; }; 01D082402C5B9EAB007FE81F /* POSBackgroundAppearanceKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01D0823F2C5B9EAB007FE81F /* POSBackgroundAppearanceKey.swift */; }; 01F067ED2D0C5D59001C5805 /* MockLocationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01F067EC2D0C5D56001C5805 /* MockLocationService.swift */; }; @@ -377,7 +378,6 @@ 0269A63C2581D26C007B49ED /* ShippingLabelPrintingStepListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0269A63B2581D26C007B49ED /* ShippingLabelPrintingStepListView.swift */; }; 026A23FF2A3173F100EFE4BD /* MockBlazeEligibilityChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 026A23FE2A3173F100EFE4BD /* MockBlazeEligibilityChecker.swift */; }; 026A50282D2F6BD1002C42C2 /* InfiniteScrollTriggerDeterminable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 026A50272D2F6BD1002C42C2 /* InfiniteScrollTriggerDeterminable.swift */; }; - 026A502C2D2F6CC3002C42C2 /* View+Measurements.swift in Sources */ = {isa = PBXBuildFile; fileRef = 026A502B2D2F6CC3002C42C2 /* View+Measurements.swift */; }; 026A50302D2F80B5002C42C2 /* ThresholdInfiniteScrollTriggerDeterminerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 026A502F2D2F80B5002C42C2 /* ThresholdInfiniteScrollTriggerDeterminerTests.swift */; }; 026B2D172DF92291005B8CAA /* POSTabEligibilityChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 026B2D162DF92290005B8CAA /* POSTabEligibilityChecker.swift */; }; 026B3C57249A046E00F7823C /* TextFieldTextAlignment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 026B3C56249A046E00F7823C /* TextFieldTextAlignment.swift */; }; @@ -631,7 +631,6 @@ 02EA6BF82435E80600FFF90A /* ImageDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02EA6BF72435E80600FFF90A /* ImageDownloader.swift */; }; 02EA6BFA2435E92600FFF90A /* KingfisherImageDownloader+ImageDownloadable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02EA6BF92435E92600FFF90A /* KingfisherImageDownloader+ImageDownloadable.swift */; }; 02EA6BFC2435EC3500FFF90A /* MockImageDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02EA6BFB2435EC3500FFF90A /* MockImageDownloader.swift */; }; - 02EAA4CA2911004B00918DAB /* TextFieldStyles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02EAA4C92911004B00918DAB /* TextFieldStyles.swift */; }; 02EAF5BE29FA04750058071C /* ProductDescriptionGenerationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02EAF5BD29FA04750058071C /* ProductDescriptionGenerationView.swift */; }; 02EAF5C029FA04850058071C /* ProductDescriptionGenerationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02EAF5BF29FA04850058071C /* ProductDescriptionGenerationViewModel.swift */; }; 02EAF5C329FA30FF0058071C /* ProductDescriptionGenerationViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02EAF5C229FA30FF0058071C /* ProductDescriptionGenerationViewModelTests.swift */; }; @@ -695,7 +694,6 @@ 0365986B29AFB11E00F297D3 /* SetUpTapToPayInformationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0365986A29AFB11E00F297D3 /* SetUpTapToPayInformationViewController.swift */; }; 0366EAE12909A37800B51755 /* JustInTimeMessageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0366EAE02909A37800B51755 /* JustInTimeMessageViewModel.swift */; }; 036CA6B9291E8D4B00E4DF4F /* CardPresentModalPreparingForPayment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 036CA6B8291E8D4B00E4DF4F /* CardPresentModalPreparingForPayment.swift */; }; - 036CA6F129229C9E00E4DF4F /* IndefiniteCircularProgressViewStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 036CA6F029229C9E00E4DF4F /* IndefiniteCircularProgressViewStyle.swift */; }; 036F6EA6281847D5006D84F8 /* PaymentCaptureOrchestratorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 036F6EA5281847D5006D84F8 /* PaymentCaptureOrchestratorTests.swift */; }; 0371C3682875E47B00277E2C /* FeatureAnnouncementCardViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0371C3672875E47B00277E2C /* FeatureAnnouncementCardViewModel.swift */; }; 0371C36A2876DBCA00277E2C /* FeatureAnnouncementCardViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0371C3692876DBCA00277E2C /* FeatureAnnouncementCardViewModelTests.swift */; }; @@ -799,7 +797,6 @@ 2004E2C42C076D3800D62521 /* CardPresentPaymentEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2004E2C32C076D3800D62521 /* CardPresentPaymentEvent.swift */; }; 2004E2C62C076D4500D62521 /* CardPresentPaymentResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2004E2C52C076D4500D62521 /* CardPresentPaymentResult.swift */; }; 2004E2CA2C07771400D62521 /* CardPresentPaymentReaderConnectionResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2004E2C92C07771400D62521 /* CardPresentPaymentReaderConnectionResult.swift */; }; - 2004E2CC2C07795E00D62521 /* CardPresentPaymentError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2004E2CB2C07795E00D62521 /* CardPresentPaymentError.swift */; }; 2004E2CE2C077B0B00D62521 /* CardPresentPaymentCardReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2004E2CD2C077B0B00D62521 /* CardPresentPaymentCardReader.swift */; }; 2004E2D02C077D2800D62521 /* CardPresentPaymentTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2004E2CF2C077D2800D62521 /* CardPresentPaymentTransaction.swift */; }; 2004E2D22C07878E00D62521 /* CardReaderConnectionMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2004E2D12C07878E00D62521 /* CardReaderConnectionMethod.swift */; }; @@ -904,7 +901,6 @@ 209B7A682CEB6742003BDEF0 /* PointOfSalePaymentState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 209B7A672CEB6742003BDEF0 /* PointOfSalePaymentState.swift */; }; 209C60FD2DCCFC7100AB2D39 /* POSPreSearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 20050F182DC3E37400E12021 /* POSPreSearchView.swift */; }; 209CA0EE2B50070D0073D1AC /* WooTabContainerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 209CA0ED2B50070D0073D1AC /* WooTabContainerController.swift */; }; - 209E96BD2DB681B50089F3D2 /* KeyboardObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 209E96BC2DB681B50089F3D2 /* KeyboardObserver.swift */; }; 209ECA812DB8FC280089F3D2 /* PointOfSaleViewStateCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 209ECA802DB8FC280089F3D2 /* PointOfSaleViewStateCoordinator.swift */; }; 209EE8132DBA95BA0089F3D2 /* POSSearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 209EE8122DBA95BA0089F3D2 /* POSSearchView.swift */; }; 209EE8152DBA96D00089F3D2 /* POSProductSearchable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 209EE8142DBA96D00089F3D2 /* POSProductSearchable.swift */; }; @@ -1042,7 +1038,6 @@ 2662D90826E15D6E00E25611 /* AreaSelectorCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2662D90726E15D6E00E25611 /* AreaSelectorCommand.swift */; }; 2662D90A26E16B3600E25611 /* FilterListSelector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2662D90926E16B3600E25611 /* FilterListSelector.swift */; }; 2664210126F3E1BB001FC5B4 /* ModalHostingPresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2664210026F3E1BB001FC5B4 /* ModalHostingPresentationController.swift */; }; - 2664210326F40FB1001FC5B4 /* View+ScrollModifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2664210226F40FB1001FC5B4 /* View+ScrollModifiers.swift */; }; 2667BFD7252E5DBF008099D4 /* RefundItemViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2667BFD6252E5DBF008099D4 /* RefundItemViewModelTests.swift */; }; 2667BFDB252E659A008099D4 /* MockOrderItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2667BFDA252E659A008099D4 /* MockOrderItem.swift */; }; 2667BFDD252F61C5008099D4 /* RefundShippingDetailsViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2667BFDC252F61C5008099D4 /* RefundShippingDetailsViewModelTests.swift */; }; @@ -1177,7 +1172,6 @@ 26DDA4A92C4839B8005FBEBF /* DashboardTimestampStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26DDA4A82C4839B8005FBEBF /* DashboardTimestampStore.swift */; }; 26DDA4AB2C49627F005FBEBF /* DashboardTimestampStoreTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26DDA4AA2C49627F005FBEBF /* DashboardTimestampStoreTests.swift */; }; 26E0ADF12631D94D00A5EB3B /* TopBannerWrapperView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26E0ADF02631D94D00A5EB3B /* TopBannerWrapperView.swift */; }; - 26E0AE13263359F900A5EB3B /* View+Conditionals.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26E0AE12263359F900A5EB3B /* View+Conditionals.swift */; }; 26E0AE1926335AA900A5EB3B /* Survey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26E0AE1826335AA900A5EB3B /* Survey.swift */; }; 26E1BECA251BE5390096D0A1 /* RefundItemTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26E1BEC9251BE5390096D0A1 /* RefundItemTableViewCell.swift */; }; 26E1BECC251BE5570096D0A1 /* RefundItemTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 26E1BECB251BE5570096D0A1 /* RefundItemTableViewCell.xib */; }; @@ -1236,7 +1230,6 @@ 314DC4BF268D183600444C9E /* CardReaderSettingsKnownReaderStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 314DC4BE268D183600444C9E /* CardReaderSettingsKnownReaderStorage.swift */; }; 314DC4C1268D28B100444C9E /* CardReaderSettingsKnownReadersStorageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 314DC4C0268D28B100444C9E /* CardReaderSettingsKnownReadersStorageTests.swift */; }; 314DC4C3268D2F1000444C9E /* MockAppSettingsStoresManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 314DC4C2268D2F1000444C9E /* MockAppSettingsStoresManager.swift */; }; - 31579028273EE2B1008CA3AF /* VersionHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31579027273EE2B1008CA3AF /* VersionHelpers.swift */; }; 31595CAD25E966380033F0FF /* ConnectedReaderTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 31595CAC25E966380033F0FF /* ConnectedReaderTableViewCell.xib */; }; 315E14F42698DA24000AD5FF /* PassKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 315E14F32698DA24000AD5FF /* PassKit.framework */; }; 316837DA25CCA90C00E36B2F /* OrderStatusListDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 316837D925CCA90C00E36B2F /* OrderStatusListDataSource.swift */; }; @@ -1263,7 +1256,6 @@ 31F21B02263C8E150035B50A /* CardReaderSettingsSearchingViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31F21B01263C8E150035B50A /* CardReaderSettingsSearchingViewModelTests.swift */; }; 31F21B5A263CB41A0035B50A /* MockCardPresentPaymentsStoresManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31F21B59263CB41A0035B50A /* MockCardPresentPaymentsStoresManager.swift */; }; 31F21B60263CB78A0035B50A /* MockCardReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31F21B5F263CB78A0035B50A /* MockCardReader.swift */; }; - 31F635DC273AF0B100E14F10 /* VersionHelpersTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31F635DB273AF0B100E14F10 /* VersionHelpersTests.swift */; }; 31F92DE125E85F6A00DE04DF /* ConnectedReaderTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31F92DE025E85F6A00DE04DF /* ConnectedReaderTableViewCell.swift */; }; 31FC8CE727B47591004B9456 /* CardReaderSettingsDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31FC8CE627B47591004B9456 /* CardReaderSettingsDataSource.swift */; }; 31FC8CE927B476BA004B9456 /* CardReaderSettingsResultsControllers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31FC8CE827B476BA004B9456 /* CardReaderSettingsResultsControllers.swift */; }; @@ -1548,7 +1540,6 @@ 57EBC92024EEE61800C1D45B /* WooAnalyticsEvent+WooApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57EBC91F24EEE61800C1D45B /* WooAnalyticsEvent+WooApp.swift */; }; 57F2C6CD246DECC10074063B /* SummaryTableViewCellViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57F2C6CC246DECC10074063B /* SummaryTableViewCellViewModelTests.swift */; }; 57F42E40253768D600EA87F7 /* TitleAndEditableValueTableViewCellViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57F42E3F253768D600EA87F7 /* TitleAndEditableValueTableViewCellViewModelTests.swift */; }; - 581D5052274AA2480089B6AD /* View+AutofocusTextModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 581D5051274AA2480089B6AD /* View+AutofocusTextModifier.swift */; }; 6801E4172D0FFF0300F9DF46 /* MockReceiptService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6801E4162D0FFF0100F9DF46 /* MockReceiptService.swift */; }; 680BA59A2A4C377900F5559D /* UpgradeViewState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 680BA5992A4C377900F5559D /* UpgradeViewState.swift */; }; 680E36B52BD8B9B900E8BCEA /* OrderSubscriptionTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 680E36B42BD8B9B900E8BCEA /* OrderSubscriptionTableViewCell.xib */; }; @@ -1591,7 +1582,7 @@ 68709D3D2A2ED94900A7FA6C /* UpgradesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68709D3C2A2ED94900A7FA6C /* UpgradesView.swift */; }; 68709D402A2EE2DC00A7FA6C /* UpgradesViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68709D3F2A2EE2DC00A7FA6C /* UpgradesViewModel.swift */; }; 6879B8DB287AFFA100A0F9A8 /* CardReaderManualsViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6879B8DA287AFFA100A0F9A8 /* CardReaderManualsViewModelTests.swift */; }; - 687C006F2D6346E300F832FC /* POSCollectOrderPaymentAnalyticsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 687C006E2D6346E300F832FC /* POSCollectOrderPaymentAnalyticsTests.swift */; }; + 687C006F2D6346E300F832FC /* POSCollectOrderPaymentAnalyticsAdaptorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 687C006E2D6346E300F832FC /* POSCollectOrderPaymentAnalyticsAdaptorTests.swift */; }; 6881CCC42A5EE6BF00AEDE36 /* WooPlanCardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6881CCC32A5EE6BF00AEDE36 /* WooPlanCardView.swift */; }; 6885E2CC2C32B14B004C8D70 /* TotalsViewHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6885E2CB2C32B14B004C8D70 /* TotalsViewHelper.swift */; }; 6888A2C82A668D650026F5C0 /* FullFeatureListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6888A2C72A668D650026F5C0 /* FullFeatureListView.swift */; }; @@ -1631,13 +1622,12 @@ 68E674AB2A4DAB8C0034BA1E /* CompletedUpgradeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68E674AA2A4DAB8C0034BA1E /* CompletedUpgradeView.swift */; }; 68E674AD2A4DAC010034BA1E /* CurrentPlanDetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68E674AC2A4DAC010034BA1E /* CurrentPlanDetailsView.swift */; }; 68E674AF2A4DACD50034BA1E /* UpgradeTopBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68E674AE2A4DACD50034BA1E /* UpgradeTopBarView.swift */; }; - 68E952CC287536010095A23D /* SafariView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68E952CB287536010095A23D /* SafariView.swift */; }; 68E952D0287587BF0095A23D /* CardReaderManualRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68E952CF287587BF0095A23D /* CardReaderManualRowView.swift */; }; 68E952D22875A44B0095A23D /* CardReaderType+Manual.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68E952D12875A44B0095A23D /* CardReaderType+Manual.swift */; }; 68ED2BD62ADD2C8C00ECA88D /* LineDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68ED2BD52ADD2C8C00ECA88D /* LineDetailView.swift */; }; 68F68A502D6730E200BB9568 /* POSCollectOrderPaymentAnalyticsTracking.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68F68A4F2D6730DF00BB9568 /* POSCollectOrderPaymentAnalyticsTracking.swift */; }; 68F68A522D67365900BB9568 /* MockPOSCollectOrderPaymentAnalyticsTracker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68F68A512D67365900BB9568 /* MockPOSCollectOrderPaymentAnalyticsTracker.swift */; }; - 68F896422D5E4323000B308B /* POSCollectOrderPaymentAnalytics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68F896412D5E4321000B308B /* POSCollectOrderPaymentAnalytics.swift */; }; + 68F896422D5E4323000B308B /* POSCollectOrderPaymentAnalyticsAdaptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68F896412D5E4321000B308B /* POSCollectOrderPaymentAnalyticsAdaptor.swift */; }; 740382DB2267D94100A627F4 /* LargeImageTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 740382D92267D94100A627F4 /* LargeImageTableViewCell.swift */; }; 740382DC2267D94100A627F4 /* LargeImageTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 740382DA2267D94100A627F4 /* LargeImageTableViewCell.xib */; }; 740987B321B87760000E4C80 /* FancyAnimatedButton+Woo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 740987B221B87760000E4C80 /* FancyAnimatedButton+Woo.swift */; }; @@ -1915,7 +1905,6 @@ B58B4AB32108F01700076FDD /* DefaultNoticePresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B58B4AB02108F01600076FDD /* DefaultNoticePresenter.swift */; }; B58B4AB62108F11C00076FDD /* Notice.swift in Sources */ = {isa = PBXBuildFile; fileRef = B58B4AB52108F11C00076FDD /* Notice.swift */; }; B58B4AB82108F14700076FDD /* NoticeNotificationInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B58B4AB72108F14700076FDD /* NoticeNotificationInfo.swift */; }; - B58B4AC02108FF6100076FDD /* Array+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = B58B4ABF2108FF6100076FDD /* Array+Helpers.swift */; }; B5980A6121AC878900EBF596 /* UIDevice+Woo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5980A6021AC878900EBF596 /* UIDevice+Woo.swift */; }; B5980A6321AC879F00EBF596 /* Bundle+Woo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5980A6221AC879F00EBF596 /* Bundle+Woo.swift */; }; B5980A6521AC905C00EBF596 /* UIDeviceWooTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5980A6421AC905C00EBF596 /* UIDeviceWooTests.swift */; }; @@ -2142,8 +2131,6 @@ CC4A4E962655273D00B75DCD /* ShippingLabelPaymentMethods.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC4A4E952655273D00B75DCD /* ShippingLabelPaymentMethods.swift */; }; CC4A4ED82655478D00B75DCD /* ShippingLabelPaymentMethodsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC4A4ED72655478D00B75DCD /* ShippingLabelPaymentMethodsViewModel.swift */; }; CC4A4FF126557D0E00B75DCD /* TitleAndToggleRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC4A4FF026557D0E00B75DCD /* TitleAndToggleRow.swift */; }; - CC4B252B27CFCEE2008D2E6E /* OrderTotalsCalculator.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC4B252A27CFCEE2008D2E6E /* OrderTotalsCalculator.swift */; }; - CC4B252D27CFE443008D2E6E /* OrderTotalsCalculatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC4B252C27CFE443008D2E6E /* OrderTotalsCalculatorTests.swift */; }; CC4D1D8625E6CDDE00B6E4E7 /* RenameAttributesViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC4D1D8525E6CDDE00B6E4E7 /* RenameAttributesViewModel.swift */; }; CC4D1E7925EE415D00B6E4E7 /* RenameAttributesViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC4D1E7825EE415D00B6E4E7 /* RenameAttributesViewModelTests.swift */; }; CC53FB3527551A6E00C4CA4F /* ProductRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC53FB3427551A6E00C4CA4F /* ProductRow.swift */; }; @@ -2329,7 +2316,6 @@ CE6A8FB82B7291760063564D /* AnalyticsReportLinkViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6A8FB72B7291760063564D /* AnalyticsReportLinkViewModelTests.swift */; }; CE6E110B2C91DA5D00563DD4 /* WooShippingItemRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6E110A2C91DA5D00563DD4 /* WooShippingItemRow.swift */; }; CE6E110D2C91E5FF00563DD4 /* WooShippingItems.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6E110C2C91E5FF00563DD4 /* WooShippingItems.swift */; }; - CE6E110F2C91EF6800563DD4 /* View+RoundedBorder.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE6E110E2C91EF6800563DD4 /* View+RoundedBorder.swift */; }; CE755F712D4A4922002539F6 /* WooShippingNormalizeAddressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE755F702D4A4922002539F6 /* WooShippingNormalizeAddressView.swift */; }; CE755F732D4A5F9D002539F6 /* WooShippingNormalizeAddressViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE755F722D4A5F96002539F6 /* WooShippingNormalizeAddressViewModel.swift */; }; CE755F752D4A6BF3002539F6 /* WooShippingNormalizeAddressViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE755F742D4A6BF3002539F6 /* WooShippingNormalizeAddressViewModelTests.swift */; }; @@ -2853,7 +2839,6 @@ E1068058285C787100668B46 /* BetaFeaturesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1068057285C787100668B46 /* BetaFeaturesTests.swift */; }; E107FCE126C12B2700BAF51B /* InPersonPaymentsCountryNotSupported.swift in Sources */ = {isa = PBXBuildFile; fileRef = E107FCE026C12B2700BAF51B /* InPersonPaymentsCountryNotSupported.swift */; }; E107FCE326C13A0D00BAF51B /* InPersonPaymentsSupportLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = E107FCE226C13A0D00BAF51B /* InPersonPaymentsSupportLink.swift */; }; - E10BC15E26CC06970064F5E2 /* ScrollableVStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = E10BC15D26CC06970064F5E2 /* ScrollableVStack.swift */; }; E10BD16D27CF890800CE6449 /* InPersonPaymentsCountryNotSupportedStripe.swift in Sources */ = {isa = PBXBuildFile; fileRef = E10BD16C27CF890700CE6449 /* InPersonPaymentsCountryNotSupportedStripe.swift */; }; E10DFC78267331590083AFF2 /* ApplicationLogViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E10DFC77267331590083AFF2 /* ApplicationLogViewModelTests.swift */; }; E10DFC7A2673595A0083AFF2 /* ShareSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = E10DFC792673595A0083AFF2 /* ShareSheet.swift */; }; @@ -3264,6 +3249,7 @@ 01BD77492C58D29700147191 /* PointOfSaleCardPresentPaymentDisconnectedMessageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PointOfSaleCardPresentPaymentDisconnectedMessageView.swift; sourceTree = ""; }; 01BD774B2C58D2BE00147191 /* PointOfSaleCardPresentPaymentDisconnectedMessageViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PointOfSaleCardPresentPaymentDisconnectedMessageViewModel.swift; sourceTree = ""; }; 01BE94032DDCC7650063541C /* PointOfSaleEmptyErrorStateViewLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PointOfSaleEmptyErrorStateViewLayout.swift; sourceTree = ""; }; + 01C230E82E3A334A00621DB0 /* MockOnboardingViewFactoryConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockOnboardingViewFactoryConfiguration.swift; sourceTree = ""; }; 01C9C59E2DA3D97E00CD81D8 /* CartRowRemoveButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CartRowRemoveButton.swift; sourceTree = ""; }; 01D0823F2C5B9EAB007FE81F /* POSBackgroundAppearanceKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = POSBackgroundAppearanceKey.swift; sourceTree = ""; }; 01F067EC2D0C5D56001C5805 /* MockLocationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockLocationService.swift; sourceTree = ""; }; @@ -3545,7 +3531,6 @@ 0269A63B2581D26C007B49ED /* ShippingLabelPrintingStepListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShippingLabelPrintingStepListView.swift; sourceTree = ""; }; 026A23FE2A3173F100EFE4BD /* MockBlazeEligibilityChecker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockBlazeEligibilityChecker.swift; sourceTree = ""; }; 026A50272D2F6BD1002C42C2 /* InfiniteScrollTriggerDeterminable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfiniteScrollTriggerDeterminable.swift; sourceTree = ""; }; - 026A502B2D2F6CC3002C42C2 /* View+Measurements.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+Measurements.swift"; sourceTree = ""; }; 026A502F2D2F80B5002C42C2 /* ThresholdInfiniteScrollTriggerDeterminerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThresholdInfiniteScrollTriggerDeterminerTests.swift; sourceTree = ""; }; 026B2D162DF92290005B8CAA /* POSTabEligibilityChecker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = POSTabEligibilityChecker.swift; sourceTree = ""; }; 026B3C56249A046E00F7823C /* TextFieldTextAlignment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFieldTextAlignment.swift; sourceTree = ""; }; @@ -3801,7 +3786,6 @@ 02EA6BF72435E80600FFF90A /* ImageDownloader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageDownloader.swift; sourceTree = ""; }; 02EA6BF92435E92600FFF90A /* KingfisherImageDownloader+ImageDownloadable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "KingfisherImageDownloader+ImageDownloadable.swift"; sourceTree = ""; }; 02EA6BFB2435EC3500FFF90A /* MockImageDownloader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockImageDownloader.swift; sourceTree = ""; }; - 02EAA4C92911004B00918DAB /* TextFieldStyles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFieldStyles.swift; sourceTree = ""; }; 02EAF5BD29FA04750058071C /* ProductDescriptionGenerationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductDescriptionGenerationView.swift; sourceTree = ""; }; 02EAF5BF29FA04850058071C /* ProductDescriptionGenerationViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductDescriptionGenerationViewModel.swift; sourceTree = ""; }; 02EAF5C229FA30FF0058071C /* ProductDescriptionGenerationViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductDescriptionGenerationViewModelTests.swift; sourceTree = ""; }; @@ -3867,7 +3851,6 @@ 0365986A29AFB11E00F297D3 /* SetUpTapToPayInformationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SetUpTapToPayInformationViewController.swift; sourceTree = ""; }; 0366EAE02909A37800B51755 /* JustInTimeMessageViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JustInTimeMessageViewModel.swift; sourceTree = ""; }; 036CA6B8291E8D4B00E4DF4F /* CardPresentModalPreparingForPayment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardPresentModalPreparingForPayment.swift; sourceTree = ""; }; - 036CA6F029229C9E00E4DF4F /* IndefiniteCircularProgressViewStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IndefiniteCircularProgressViewStyle.swift; sourceTree = ""; }; 036F6EA5281847D5006D84F8 /* PaymentCaptureOrchestratorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaymentCaptureOrchestratorTests.swift; sourceTree = ""; }; 0371C3672875E47B00277E2C /* FeatureAnnouncementCardViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureAnnouncementCardViewModel.swift; sourceTree = ""; }; 0371C3692876DBCA00277E2C /* FeatureAnnouncementCardViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureAnnouncementCardViewModelTests.swift; sourceTree = ""; }; @@ -3972,7 +3955,6 @@ 2004E2C32C076D3800D62521 /* CardPresentPaymentEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardPresentPaymentEvent.swift; sourceTree = ""; }; 2004E2C52C076D4500D62521 /* CardPresentPaymentResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardPresentPaymentResult.swift; sourceTree = ""; }; 2004E2C92C07771400D62521 /* CardPresentPaymentReaderConnectionResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardPresentPaymentReaderConnectionResult.swift; sourceTree = ""; }; - 2004E2CB2C07795E00D62521 /* CardPresentPaymentError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardPresentPaymentError.swift; sourceTree = ""; }; 2004E2CD2C077B0B00D62521 /* CardPresentPaymentCardReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardPresentPaymentCardReader.swift; sourceTree = ""; }; 2004E2CF2C077D2800D62521 /* CardPresentPaymentTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardPresentPaymentTransaction.swift; sourceTree = ""; }; 2004E2D12C07878E00D62521 /* CardReaderConnectionMethod.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardReaderConnectionMethod.swift; sourceTree = ""; }; @@ -4079,7 +4061,6 @@ 209B15662AD85F070094152A /* OperatingSystemVersion+Localization.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OperatingSystemVersion+Localization.swift"; sourceTree = ""; }; 209B7A672CEB6742003BDEF0 /* PointOfSalePaymentState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PointOfSalePaymentState.swift; sourceTree = ""; }; 209CA0ED2B50070D0073D1AC /* WooTabContainerController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WooTabContainerController.swift; sourceTree = ""; }; - 209E96BC2DB681B50089F3D2 /* KeyboardObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyboardObserver.swift; sourceTree = ""; }; 209ECA802DB8FC280089F3D2 /* PointOfSaleViewStateCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PointOfSaleViewStateCoordinator.swift; sourceTree = ""; }; 209EE8122DBA95BA0089F3D2 /* POSSearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = POSSearchView.swift; sourceTree = ""; }; 209EE8142DBA96D00089F3D2 /* POSProductSearchable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = POSProductSearchable.swift; sourceTree = ""; }; @@ -4215,7 +4196,6 @@ 2662D90726E15D6E00E25611 /* AreaSelectorCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AreaSelectorCommand.swift; sourceTree = ""; }; 2662D90926E16B3600E25611 /* FilterListSelector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilterListSelector.swift; sourceTree = ""; }; 2664210026F3E1BB001FC5B4 /* ModalHostingPresentationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModalHostingPresentationController.swift; sourceTree = ""; }; - 2664210226F40FB1001FC5B4 /* View+ScrollModifiers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+ScrollModifiers.swift"; sourceTree = ""; }; 2667BFD6252E5DBF008099D4 /* RefundItemViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RefundItemViewModelTests.swift; sourceTree = ""; }; 2667BFDA252E659A008099D4 /* MockOrderItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockOrderItem.swift; sourceTree = ""; }; 2667BFDC252F61C5008099D4 /* RefundShippingDetailsViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RefundShippingDetailsViewModelTests.swift; sourceTree = ""; }; @@ -4322,7 +4302,6 @@ 26DDA4A82C4839B8005FBEBF /* DashboardTimestampStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashboardTimestampStore.swift; sourceTree = ""; }; 26DDA4AA2C49627F005FBEBF /* DashboardTimestampStoreTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashboardTimestampStoreTests.swift; sourceTree = ""; }; 26E0ADF02631D94D00A5EB3B /* TopBannerWrapperView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TopBannerWrapperView.swift; sourceTree = ""; }; - 26E0AE12263359F900A5EB3B /* View+Conditionals.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+Conditionals.swift"; sourceTree = ""; }; 26E0AE1826335AA900A5EB3B /* Survey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Survey.swift; sourceTree = ""; }; 26E1BEC9251BE5390096D0A1 /* RefundItemTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RefundItemTableViewCell.swift; sourceTree = ""; }; 26E1BECB251BE5570096D0A1 /* RefundItemTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = RefundItemTableViewCell.xib; sourceTree = ""; }; @@ -4378,7 +4357,6 @@ 314DC4BE268D183600444C9E /* CardReaderSettingsKnownReaderStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardReaderSettingsKnownReaderStorage.swift; sourceTree = ""; }; 314DC4C0268D28B100444C9E /* CardReaderSettingsKnownReadersStorageTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardReaderSettingsKnownReadersStorageTests.swift; sourceTree = ""; }; 314DC4C2268D2F1000444C9E /* MockAppSettingsStoresManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockAppSettingsStoresManager.swift; sourceTree = ""; }; - 31579027273EE2B1008CA3AF /* VersionHelpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionHelpers.swift; sourceTree = ""; }; 31595CAC25E966380033F0FF /* ConnectedReaderTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ConnectedReaderTableViewCell.xib; sourceTree = ""; }; 315E14F32698DA24000AD5FF /* PassKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PassKit.framework; path = System/Library/Frameworks/PassKit.framework; sourceTree = SDKROOT; }; 316837D925CCA90C00E36B2F /* OrderStatusListDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderStatusListDataSource.swift; sourceTree = ""; }; @@ -4406,7 +4384,6 @@ 31F21B01263C8E150035B50A /* CardReaderSettingsSearchingViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardReaderSettingsSearchingViewModelTests.swift; sourceTree = ""; }; 31F21B59263CB41A0035B50A /* MockCardPresentPaymentsStoresManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockCardPresentPaymentsStoresManager.swift; sourceTree = ""; }; 31F21B5F263CB78A0035B50A /* MockCardReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockCardReader.swift; sourceTree = ""; }; - 31F635DB273AF0B100E14F10 /* VersionHelpersTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VersionHelpersTests.swift; sourceTree = ""; }; 31F92DE025E85F6A00DE04DF /* ConnectedReaderTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectedReaderTableViewCell.swift; sourceTree = ""; }; 31FC8CE627B47591004B9456 /* CardReaderSettingsDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardReaderSettingsDataSource.swift; sourceTree = ""; }; 31FC8CE827B476BA004B9456 /* CardReaderSettingsResultsControllers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardReaderSettingsResultsControllers.swift; sourceTree = ""; }; @@ -4699,7 +4676,6 @@ 57EBC91F24EEE61800C1D45B /* WooAnalyticsEvent+WooApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WooAnalyticsEvent+WooApp.swift"; sourceTree = ""; }; 57F2C6CC246DECC10074063B /* SummaryTableViewCellViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SummaryTableViewCellViewModelTests.swift; sourceTree = ""; }; 57F42E3F253768D600EA87F7 /* TitleAndEditableValueTableViewCellViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TitleAndEditableValueTableViewCellViewModelTests.swift; sourceTree = ""; }; - 581D5051274AA2480089B6AD /* View+AutofocusTextModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+AutofocusTextModifier.swift"; sourceTree = ""; }; 6801E4162D0FFF0100F9DF46 /* MockReceiptService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockReceiptService.swift; sourceTree = ""; }; 680BA5992A4C377900F5559D /* UpgradeViewState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpgradeViewState.swift; sourceTree = ""; }; 680E36B42BD8B9B900E8BCEA /* OrderSubscriptionTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = OrderSubscriptionTableViewCell.xib; sourceTree = ""; }; @@ -4742,7 +4718,7 @@ 68709D3C2A2ED94900A7FA6C /* UpgradesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpgradesView.swift; sourceTree = ""; }; 68709D3F2A2EE2DC00A7FA6C /* UpgradesViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpgradesViewModel.swift; sourceTree = ""; }; 6879B8DA287AFFA100A0F9A8 /* CardReaderManualsViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardReaderManualsViewModelTests.swift; sourceTree = ""; }; - 687C006E2D6346E300F832FC /* POSCollectOrderPaymentAnalyticsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = POSCollectOrderPaymentAnalyticsTests.swift; sourceTree = ""; }; + 687C006E2D6346E300F832FC /* POSCollectOrderPaymentAnalyticsAdaptorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = POSCollectOrderPaymentAnalyticsAdaptorTests.swift; sourceTree = ""; }; 6881CCC32A5EE6BF00AEDE36 /* WooPlanCardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WooPlanCardView.swift; sourceTree = ""; }; 6885E2CB2C32B14B004C8D70 /* TotalsViewHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TotalsViewHelper.swift; sourceTree = ""; }; 6888A2C72A668D650026F5C0 /* FullFeatureListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FullFeatureListView.swift; sourceTree = ""; }; @@ -4782,13 +4758,12 @@ 68E674AA2A4DAB8C0034BA1E /* CompletedUpgradeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompletedUpgradeView.swift; sourceTree = ""; }; 68E674AC2A4DAC010034BA1E /* CurrentPlanDetailsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrentPlanDetailsView.swift; sourceTree = ""; }; 68E674AE2A4DACD50034BA1E /* UpgradeTopBarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpgradeTopBarView.swift; sourceTree = ""; }; - 68E952CB287536010095A23D /* SafariView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SafariView.swift; sourceTree = ""; }; 68E952CF287587BF0095A23D /* CardReaderManualRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardReaderManualRowView.swift; sourceTree = ""; }; 68E952D12875A44B0095A23D /* CardReaderType+Manual.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CardReaderType+Manual.swift"; sourceTree = ""; }; 68ED2BD52ADD2C8C00ECA88D /* LineDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LineDetailView.swift; sourceTree = ""; }; 68F68A4F2D6730DF00BB9568 /* POSCollectOrderPaymentAnalyticsTracking.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = POSCollectOrderPaymentAnalyticsTracking.swift; sourceTree = ""; }; 68F68A512D67365900BB9568 /* MockPOSCollectOrderPaymentAnalyticsTracker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockPOSCollectOrderPaymentAnalyticsTracker.swift; sourceTree = ""; }; - 68F896412D5E4321000B308B /* POSCollectOrderPaymentAnalytics.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = POSCollectOrderPaymentAnalytics.swift; sourceTree = ""; }; + 68F896412D5E4321000B308B /* POSCollectOrderPaymentAnalyticsAdaptor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = POSCollectOrderPaymentAnalyticsAdaptor.swift; sourceTree = ""; }; 740382D92267D94100A627F4 /* LargeImageTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LargeImageTableViewCell.swift; sourceTree = ""; }; 740382DA2267D94100A627F4 /* LargeImageTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = LargeImageTableViewCell.xib; sourceTree = ""; }; 740987B221B87760000E4C80 /* FancyAnimatedButton+Woo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FancyAnimatedButton+Woo.swift"; sourceTree = ""; }; @@ -5095,7 +5070,6 @@ B58B4AB02108F01600076FDD /* DefaultNoticePresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DefaultNoticePresenter.swift; sourceTree = ""; }; B58B4AB52108F11C00076FDD /* Notice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notice.swift; sourceTree = ""; }; B58B4AB72108F14700076FDD /* NoticeNotificationInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeNotificationInfo.swift; sourceTree = ""; }; - B58B4ABF2108FF6100076FDD /* Array+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array+Helpers.swift"; sourceTree = ""; }; B5980A6021AC878900EBF596 /* UIDevice+Woo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIDevice+Woo.swift"; sourceTree = ""; }; B5980A6221AC879F00EBF596 /* Bundle+Woo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Bundle+Woo.swift"; sourceTree = ""; }; B5980A6421AC905C00EBF596 /* UIDeviceWooTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIDeviceWooTests.swift; sourceTree = ""; }; @@ -5323,8 +5297,6 @@ CC4A4E952655273D00B75DCD /* ShippingLabelPaymentMethods.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShippingLabelPaymentMethods.swift; sourceTree = ""; }; CC4A4ED72655478D00B75DCD /* ShippingLabelPaymentMethodsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShippingLabelPaymentMethodsViewModel.swift; sourceTree = ""; }; CC4A4FF026557D0E00B75DCD /* TitleAndToggleRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TitleAndToggleRow.swift; sourceTree = ""; }; - CC4B252A27CFCEE2008D2E6E /* OrderTotalsCalculator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderTotalsCalculator.swift; sourceTree = ""; }; - CC4B252C27CFE443008D2E6E /* OrderTotalsCalculatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderTotalsCalculatorTests.swift; sourceTree = ""; }; CC4D1D8525E6CDDE00B6E4E7 /* RenameAttributesViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RenameAttributesViewModel.swift; sourceTree = ""; }; CC4D1E7825EE415D00B6E4E7 /* RenameAttributesViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RenameAttributesViewModelTests.swift; sourceTree = ""; }; CC53FB3427551A6E00C4CA4F /* ProductRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductRow.swift; sourceTree = ""; }; @@ -5513,7 +5485,6 @@ CE6A8FB72B7291760063564D /* AnalyticsReportLinkViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsReportLinkViewModelTests.swift; sourceTree = ""; }; CE6E110A2C91DA5D00563DD4 /* WooShippingItemRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WooShippingItemRow.swift; sourceTree = ""; }; CE6E110C2C91E5FF00563DD4 /* WooShippingItems.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WooShippingItems.swift; sourceTree = ""; }; - CE6E110E2C91EF6800563DD4 /* View+RoundedBorder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+RoundedBorder.swift"; sourceTree = ""; }; CE7269C72D11A99800D565C1 /* WooShippingAddPackageViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WooShippingAddPackageViewModelTests.swift; sourceTree = ""; }; CE755F702D4A4922002539F6 /* WooShippingNormalizeAddressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WooShippingNormalizeAddressView.swift; sourceTree = ""; }; CE755F722D4A5F96002539F6 /* WooShippingNormalizeAddressViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WooShippingNormalizeAddressViewModel.swift; sourceTree = ""; }; @@ -6032,7 +6003,6 @@ E1068057285C787100668B46 /* BetaFeaturesTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BetaFeaturesTests.swift; sourceTree = ""; }; E107FCE026C12B2700BAF51B /* InPersonPaymentsCountryNotSupported.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InPersonPaymentsCountryNotSupported.swift; sourceTree = ""; }; E107FCE226C13A0D00BAF51B /* InPersonPaymentsSupportLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InPersonPaymentsSupportLink.swift; sourceTree = ""; }; - E10BC15D26CC06970064F5E2 /* ScrollableVStack.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollableVStack.swift; sourceTree = ""; }; E10BD16C27CF890700CE6449 /* InPersonPaymentsCountryNotSupportedStripe.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InPersonPaymentsCountryNotSupportedStripe.swift; sourceTree = ""; }; E10DFC77267331590083AFF2 /* ApplicationLogViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationLogViewModelTests.swift; sourceTree = ""; }; E10DFC792673595A0083AFF2 /* ShareSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareSheet.swift; sourceTree = ""; }; @@ -6451,6 +6421,7 @@ children = ( 01C216DB2E390ED700621DB0 /* Card Present Payments */, 017DCD4D2E38E56500EC1605 /* POSServiceLocatorAdaptor.swift */, + 68F896412D5E4321000B308B /* POSCollectOrderPaymentAnalyticsAdaptor.swift */, ); path = Adaptors; sourceTree = ""; @@ -6500,10 +6471,23 @@ 2004E2D52C08E1FA00D62521 /* CardPresentPaymentOnboardingAdaptor.swift */, 027179E12C08817F0049F0BD /* CardPresentPaymentService.swift */, 2004E2E42C0A206800D62521 /* CardPresentPaymentsAlertPresenterAdaptor.swift */, + 2026ECE82C25D21F00BEF7E4 /* CardPresentPaymentInvalidatablePaymentOrchestrator.swift */, + 2004E2E22C0A128400D62521 /* CardPresentPaymentsConnectionControllerManager.swift */, + 20762BA02C18A66400758305 /* CardPresentPaymentTapToPayReaderConnectionAlertsProvider.swift */, + 20762BA42C18B42C00758305 /* CardPresentPaymentBluetoothReaderConnectionAlertsProvider.swift */, + 20762BA62C18B55100758305 /* CardPresentPaymentsTransactionAlertsProvider.swift */, ); path = "Card Present Payments"; sourceTree = ""; }; + 01C230EA2E3A3B8200621DB0 /* Adaptors */ = { + isa = PBXGroup; + children = ( + 687C006E2D6346E300F832FC /* POSCollectOrderPaymentAnalyticsAdaptorTests.swift */, + ); + path = Adaptors; + sourceTree = ""; + }; 01F935542DFC0C3B00B50B03 /* Audio */ = { isa = PBXGroup; children = ( @@ -7721,6 +7705,7 @@ 02CD3BFC2C35D01600E575C4 /* Mocks */ = { isa = PBXGroup; children = ( + 01C230E82E3A334A00621DB0 /* MockOnboardingViewFactoryConfiguration.swift */, 01F935582DFC0D4800B50B03 /* MockPointOfSaleSoundPlayer.swift */, 01AB2D152DDC8CD600AA67FD /* MockAnalytics.swift */, 686A71B72DC9EB6D0006E835 /* MockPOSSearchHistoryService.swift */, @@ -7755,7 +7740,6 @@ isa = PBXGroup; children = ( 68F68A4F2D6730DF00BB9568 /* POSCollectOrderPaymentAnalyticsTracking.swift */, - 68F896412D5E4321000B308B /* POSCollectOrderPaymentAnalytics.swift */, 20F6A46B2DE5FCEF0066D8CB /* POSItemFetchAnalytics.swift */, ); path = Analytics; @@ -8120,19 +8104,13 @@ 2004E2C52C076D4500D62521 /* CardPresentPaymentResult.swift */, 2004E2C92C07771400D62521 /* CardPresentPaymentReaderConnectionResult.swift */, 2027F7552C90B013004BDF73 /* CardPresentPaymentReaderConnectionStatus.swift */, - 2004E2CB2C07795E00D62521 /* CardPresentPaymentError.swift */, 2004E2CD2C077B0B00D62521 /* CardPresentPaymentCardReader.swift */, 2004E2D12C07878E00D62521 /* CardReaderConnectionMethod.swift */, 2004E2CF2C077D2800D62521 /* CardPresentPaymentTransaction.swift */, 2004E2D72C08E56300D62521 /* CardPresentPaymentOnboardingPresentationEvent.swift */, - 20762BA02C18A66400758305 /* CardPresentPaymentTapToPayReaderConnectionAlertsProvider.swift */, - 20762BA42C18B42C00758305 /* CardPresentPaymentBluetoothReaderConnectionAlertsProvider.swift */, - 20762BA62C18B55100758305 /* CardPresentPaymentsTransactionAlertsProvider.swift */, 20ADE9422C6B34D100C91265 /* CardPresentPaymentsRetryApproach.swift */, 20762BA22C18A6A300758305 /* CardPresentPaymentEventDetails.swift */, 204CB80F2C10BB88000C9773 /* CardPresentPaymentPreviewService.swift */, - 2026ECE82C25D21F00BEF7E4 /* CardPresentPaymentInvalidatablePaymentOrchestrator.swift */, - 2004E2E22C0A128400D62521 /* CardPresentPaymentsConnectionControllerManager.swift */, 2004E2E62C0DFB9E00D62521 /* CardPresentPaymentsModalButtonViewModel.swift */, ); path = "Card Present Payments"; @@ -8402,7 +8380,6 @@ 269098B527D2C09D001FEB07 /* ShippingInputTransformerTests.swift */, 269098B927D6922E001FEB07 /* FeesInputTransformerTests.swift */, 2602A64927BDC80200B347F1 /* RemoteOrderSynchronizerTests.swift */, - CC4B252C27CFE443008D2E6E /* OrderTotalsCalculatorTests.swift */, EEB221A429B97F8400662A12 /* CouponInputTransformerTests.swift */, ); path = Synchronizer; @@ -8482,10 +8459,7 @@ 262A097F2628A8BF0033AD20 /* View Modifiers */ = { isa = PBXGroup; children = ( - 2664210226F40FB1001FC5B4 /* View+ScrollModifiers.swift */, - 26E0AE12263359F900A5EB3B /* View+Conditionals.swift */, DE4B3B5526A68DD000EEF2D8 /* View+InsetPaddings.swift */, - 581D5051274AA2480089B6AD /* View+AutofocusTextModifier.swift */, 26281775278F0B0100C836D3 /* View+NoticesModifier.swift */, AE77EA4F27A47C99006A21BD /* View+AddingDividers.swift */, AED089F127C794BC0020AE10 /* View+CurrencySymbol.swift */, @@ -8493,8 +8467,6 @@ 02562ACF296D1FD100980404 /* View+DividerStyle.swift */, B649BC7D2A1C295B007AB988 /* View+HighlightModifier.swift */, 02B60DFA2A58809F004C47FF /* View+MediaSourceActionSheet.swift */, - CE6E110E2C91EF6800563DD4 /* View+RoundedBorder.swift */, - 026A502B2D2F6CC3002C42C2 /* View+Measurements.swift */, ); path = "View Modifiers"; sourceTree = ""; @@ -8798,7 +8770,6 @@ 2602A63E27BD880A00B347F1 /* NewOrderInitialStatusResolver.swift */, 269098B327D2BBFC001FEB07 /* ShippingInputTransformer.swift */, 269098B727D68CCD001FEB07 /* FeesInputTransformer.swift */, - CC4B252A27CFCEE2008D2E6E /* OrderTotalsCalculator.swift */, EEB4E2DD29B61AAD00371C3C /* CouponInputTransformer.swift */, ); path = Synchronizer; @@ -9524,7 +9495,6 @@ CE4FE7D72B7D306200F66DD5 /* MultiSelectionReorderableList.swift */, CC254F2C26C17AB5005F3C82 /* BottomButtonView.swift */, DE19BB1126C3811100AB70D9 /* LearnMoreRow.swift */, - E10BC15D26CC06970064F5E2 /* ScrollableVStack.swift */, DE126D0A26CA2331007F901D /* ValidationErrorRow.swift */, 456BEFB526D912EC002AC16C /* AuthenticatedWebView.swift */, DEE6437726D8DAD900888A75 /* InProgressView.swift */, @@ -9547,8 +9517,6 @@ 03076D39290C22BE008EE839 /* WebView.swift */, 03076D35290C162E008EE839 /* WebViewSheet.swift */, 03076D37290C223D008EE839 /* WooNavigationSheet.swift */, - 02EAA4C92911004B00918DAB /* TextFieldStyles.swift */, - 036CA6F029229C9E00E4DF4F /* IndefiniteCircularProgressViewStyle.swift */, DE2FE5872925DD950018040A /* JetpackInstallHeaderView.swift */, 26E7EE6F29300F6200793045 /* DeltaTag.swift */, AEE9A87F293A3E5500227C92 /* RefreshablePlainList.swift */, @@ -9573,7 +9541,6 @@ CEE02AF72C1859B400B0B6AB /* MessageComposeView.swift */, DE8AA0B42BBEBE590084D2CC /* ViewControllerContainer.swift */, CE9F60112C09D53500652E0A /* FeedbackBannerPopover.swift */, - 209E96BC2DB681B50089F3D2 /* KeyboardObserver.swift */, ); path = "SwiftUI Components"; sourceTree = ""; @@ -9888,14 +9855,6 @@ path = InAppPurchases; sourceTree = ""; }; - 687C006C2D63469F00F832FC /* Analytics */ = { - isa = PBXGroup; - children = ( - 687C006E2D6346E300F832FC /* POSCollectOrderPaymentAnalyticsTests.swift */, - ); - path = Analytics; - sourceTree = ""; - }; 68B3BA242D91473D0000B2F2 /* AI Settings */ = { isa = PBXGroup; children = ( @@ -10618,7 +10577,6 @@ CE22709E2293052700C0626C /* WebviewHelper.swift */, 45D685FD23D0FB25005F87D0 /* Throttler.swift */, 262C921E26EEF8B100011F92 /* Binding.swift */, - 31579027273EE2B1008CA3AF /* VersionHelpers.swift */, 174CA86D27DBFD2D00126524 /* ShareAppTextItemActivitySource.swift */, B9C4AB2427FDE4B6007008B8 /* CardPresentPluginsDataProvider.swift */, B958A7D428B5302500823EEF /* URLOpener.swift */, @@ -10876,7 +10834,6 @@ 74F301592200EC0800931B9E /* NSDecimalNumberWooTests.swift */, 45DB706B26161F970064A6CF /* DecimalWooTests.swift */, B541B2122189E7FD008FE7C1 /* ScannerWooTests.swift */, - 31F635DB273AF0B100E14F10 /* VersionHelpersTests.swift */, B55BC1F221A8790F0011A0C0 /* StringHTMLTests.swift */, B5980A6421AC905C00EBF596 /* UIDeviceWooTests.swift */, B57C745020F56EE900EEFC87 /* UITableViewCellHelpersTests.swift */, @@ -11970,7 +11927,6 @@ 2004E2DB2C08E95B00D62521 /* ViewControllerPresenting.swift */, DE50294828BEF4CF00551736 /* WordPressOrgCredentials+Authenticator.swift */, EE3D1E932B8EC1E00016B132 /* BlazeCampaignListItem+Customizations.swift */, - B58B4ABF2108FF6100076FDD /* Array+Helpers.swift */, B59C09D82188CBB100AB41D6 /* Array+Notes.swift */, 45EF7983244F26BB00B22BA2 /* Array+IndexPath.swift */, B5980A6221AC879F00EBF596 /* Bundle+Woo.swift */, @@ -13012,7 +12968,7 @@ DABF35242C11B40C006AF826 /* POS */ = { isa = PBXGroup; children = ( - 687C006C2D63469F00F832FC /* Analytics */, + 01C230EA2E3A3B8200621DB0 /* Adaptors */, 200BA15C2CF0A9D90006DC5B /* Controllers */, 20ADE9442C6B361500C91265 /* Card Present Payments */, DAD988C72C4A9D49009DE9E3 /* Models */, @@ -13748,7 +13704,6 @@ E1ABAEF628479E0300F40BB2 /* InPersonPaymentsSelectPluginView.swift */, 684AB8392870677F003DFDD1 /* CardReaderManualsView.swift */, 684AB83B2873DF04003DFDD1 /* CardReaderManualsViewModel.swift */, - 68E952CB287536010095A23D /* SafariView.swift */, 68E952CF287587BF0095A23D /* CardReaderManualRowView.swift */, 68E952D12875A44B0095A23D /* CardReaderType+Manual.swift */, 03EF24FB28BF996F006A033E /* InPersonPaymentsCashOnDeliveryPaymentGatewayHelpers.swift */, @@ -15126,7 +15081,6 @@ 0191301B2CF4E782008C0C88 /* TapToPayEducationStepViewModel.swift in Sources */, 0258D9492B68E7FE00D280D0 /* ProductsSplitViewWrapperController.swift in Sources */, 019630B62D02018C00219D80 /* TapToPayAwarenessMomentDeterminer.swift in Sources */, - 036CA6F129229C9E00E4DF4F /* IndefiniteCircularProgressViewStyle.swift in Sources */, 451A9973260E39270059D135 /* ShippingLabelPackageNumberRow.swift in Sources */, AEE2610F26E664CE00B142A0 /* EditOrderAddressFormViewModel.swift in Sources */, 025C00BA25514A7100FAC222 /* BarcodeScannerFrameScaler.swift in Sources */, @@ -15307,7 +15261,6 @@ B5D1AFC620BC7B7300DB0E8C /* StorePickerViewController.swift in Sources */, 02DD81FB242CAA400060E50B /* WordPressMediaLibraryPickerDataSource.swift in Sources */, DE4D239829ADF8E3003A4B5D /* WordPressAuthenticator+Woo.swift in Sources */, - 31579028273EE2B1008CA3AF /* VersionHelpers.swift in Sources */, CCD2F51C26D697860010E679 /* ShippingLabelServicePackageListViewModel.swift in Sources */, 03076D38290C223E008EE839 /* WooNavigationSheet.swift in Sources */, 022CE91A29BB143000F210E0 /* ProductSelectorNavigationView.swift in Sources */, @@ -15509,7 +15462,6 @@ B57B678A2107546E00AF8905 /* Address+Woo.swift in Sources */, 035F2308275690970019E1B0 /* CardPresentModalConnectingFailedUpdatePostalCode.swift in Sources */, 205E79512C207FAE001BA266 /* PointOfSaleCardPresentPaymentDisplayReaderMessageMessageView.swift in Sources */, - 209E96BD2DB681B50089F3D2 /* KeyboardObserver.swift in Sources */, 03F5CB012A0BA3D40026877A /* ModalOverlay.swift in Sources */, 01C9C59F2DA3D98400CD81D8 /* CartRowRemoveButton.swift in Sources */, 457509E4267B9E91005FA2EA /* AggregatedProductListViewController.swift in Sources */, @@ -15545,7 +15497,6 @@ 027ADB752D218A8D009608DB /* POSItemCardBorderStylesModifier.swift in Sources */, 0215320B24231D5A003F2BBD /* UIStackView+Subviews.swift in Sources */, 02F4F50B237AEB8A00E13A9C /* ProductFormTableViewDataSource.swift in Sources */, - 2004E2CC2C07795E00D62521 /* CardPresentPaymentError.swift in Sources */, B57C5C9621B80E5500FF82B2 /* Dictionary+Woo.swift in Sources */, 68DF5A8F2CB38F20000154C9 /* OrderCouponSectionView.swift in Sources */, CE27257F21925AE8002B22EB /* ValueOneTableViewCell.swift in Sources */, @@ -15630,7 +15581,6 @@ 035DBA47292D0995003E5125 /* CardPresentPaymentPreflightController.swift in Sources */, 0230B4D82C3345DF00F2F660 /* PointOfSaleCardPresentPaymentCaptureFailedView.swift in Sources */, 86B3E2552C6B1F160002420B /* HelpAndSupportViewModel.swift in Sources */, - B58B4AC02108FF6100076FDD /* Array+Helpers.swift in Sources */, B90C65CD29ACE2D6004CAB9E /* CardPresentPaymentOnboardingStateCache.swift in Sources */, 028AFFB32484ED2800693C09 /* Dictionary+Logging.swift in Sources */, 026CAF802AC2B7FF002D23BB /* ConfigurableBundleProductView.swift in Sources */, @@ -15708,7 +15658,6 @@ 03076D3A290C22BE008EE839 /* WebView.swift in Sources */, 02E4908D29AF216E005942AE /* TopPerformersPeriodView.swift in Sources */, 023D877925EC8BCB00625963 /* UIScrollView+LargeTitleWorkaround.swift in Sources */, - 2664210326F40FB1001FC5B4 /* View+ScrollModifiers.swift in Sources */, 02695770237281A9001BA0BF /* AztecTextViewAttachmentHandler.swift in Sources */, CCCFFC5A2934EF5E006130AF /* StatsIntervalDataParser.swift in Sources */, DE5746342B4512900034B10D /* BlazeBudgetSettingView.swift in Sources */, @@ -15764,7 +15713,7 @@ 026826C02BF59E410036F959 /* PointOfSaleCardPresentPaymentConnectingFailedView.swift in Sources */, B586906621A5F4B1001F1EFC /* UINavigationController+Woo.swift in Sources */, 45FBDF3A238D3F8B00127F77 /* ExtendedAddProductImageCollectionViewCell.swift in Sources */, - 68F896422D5E4323000B308B /* POSCollectOrderPaymentAnalytics.swift in Sources */, + 68F896422D5E4323000B308B /* POSCollectOrderPaymentAnalyticsAdaptor.swift in Sources */, 029F53182BEB33BC00E31A10 /* CollapsibleCustomerCardAddressView.swift in Sources */, CE606D832BE14010001CB424 /* ShippingLineSelectionDetailsViewModel.swift in Sources */, 02C7EE8A2B21B951008B7DF8 /* ProductWithQuantityStepperViewModel.swift in Sources */, @@ -15926,7 +15875,6 @@ 028E1F702833DD0A001F8829 /* DashboardViewModel.swift in Sources */, 2602A63D27BD3C8C00B347F1 /* RemoteOrderSynchronizer.swift in Sources */, CCFBBCFA29C4C85F0081B595 /* ComponentSettingsViewModel.swift in Sources */, - CC4B252B27CFCEE2008D2E6E /* OrderTotalsCalculator.swift in Sources */, 8625C5112BF20990007F1901 /* ReviewsDashboardCard.swift in Sources */, CE2DF92E2CC16C95001AA394 /* WooShippingServiceCardView.swift in Sources */, 0247F512286F73EA009C177E /* WooAnalyticsEvent+ImageUpload.swift in Sources */, @@ -15936,7 +15884,6 @@ 45DB70602614C7E80064A6CF /* ShippingLabelPackageDetailsResultsControllers.swift in Sources */, B9F148982AD5541C008FC795 /* AddCustomAmountViewModel.swift in Sources */, 027D67D1245ADDF40036B8DB /* FilterTypeViewModel+Helpers.swift in Sources */, - 581D5052274AA2480089B6AD /* View+AutofocusTextModifier.swift in Sources */, E15FC74126BC1CED00CF83E6 /* AttributedText.swift in Sources */, 0365986B29AFB11E00F297D3 /* SetUpTapToPayInformationViewController.swift in Sources */, 31316F9C25CB20FD00D9F129 /* OrderStatusListViewModel.swift in Sources */, @@ -16120,7 +16067,6 @@ 262EB5B0298C7C3A009DCC36 /* SupportFormsDataSources.swift in Sources */, 57C5FF7F250925C90074EC26 /* OrderListViewModel.swift in Sources */, 029D02602C231F5F00CB1E75 /* PointOfSaleCardPresentPaymentReaderUpdateCompletionView.swift in Sources */, - 26E0AE13263359F900A5EB3B /* View+Conditionals.swift in Sources */, CE583A072107849F00D73C1C /* SwitchTableViewCell.swift in Sources */, EE7E75A82D83EB1F00E6FF5B /* WooShippingSplitShipmentsRow.swift in Sources */, D8149F562251EE300006A245 /* UITextField+Helpers.swift in Sources */, @@ -16158,7 +16104,6 @@ 4596853F2540669900D17B90 /* DownloadableFileSource.swift in Sources */, 021DD44D286A3A8D004F0468 /* UIViewController+Navigation.swift in Sources */, B958A7CB28B3D4A100823EEF /* RouteMatcher.swift in Sources */, - CE6E110F2C91EF6800563DD4 /* View+RoundedBorder.swift in Sources */, 0279F0E4252DC9670098D7DE /* ProductVariationLoadUseCase.swift in Sources */, 0366EAE12909A37800B51755 /* JustInTimeMessageViewModel.swift in Sources */, CCF87BC02790582500461C43 /* ProductVariationSelectorView.swift in Sources */, @@ -16327,7 +16272,6 @@ 02E222C829FBA60F004579A1 /* WooAnalyticsEvent+ProductFormAI.swift in Sources */, D8815B132638686200EDAD62 /* CardPresentModalError.swift in Sources */, 020ACF88299A809000B3638B /* LearnMoreAttributedText.swift in Sources */, - 02EAA4CA2911004B00918DAB /* TextFieldStyles.swift in Sources */, 453DBF8E2387F34A006762A5 /* UICollectionViewCell+Helpers.swift in Sources */, 45B9C63E23A8E50D007FC4C5 /* ProductPriceSettingsViewController.swift in Sources */, 318853362639FC9C00F66A9C /* PaymentSettingsFlowPresentingViewController.swift in Sources */, @@ -16346,7 +16290,6 @@ 021125992578D9C20075AD2A /* ShippingLabelPrintingInstructionsView.swift in Sources */, 026826C72BF59E410036F959 /* PointOfSaleCardPresentPaymentScanningForReadersView.swift in Sources */, EEBB81712D8C0839008D6CE5 /* CollapsibleShipmentItemCard.swift in Sources */, - 68E952CC287536010095A23D /* SafariView.swift in Sources */, D449C51C26DE6B5000D75B02 /* IconListItem.swift in Sources */, EE9D03182B89E2B10077CED1 /* OrderStatusEnum+Analytics.swift in Sources */, 014371272DFC8E2800C0279B /* PointOfSaleBarcodeScannerInformationModal.swift in Sources */, @@ -16608,7 +16551,6 @@ 203163B72C1C5EDF001C96DA /* PointOfSaleCardPresentPaymentConnectingFailedChargeReaderView.swift in Sources */, 026B2D172DF92291005B8CAA /* POSTabEligibilityChecker.swift in Sources */, 2004E2ED2C0F5DD800D62521 /* CardPresentPaymentCollectOrderPaymentUseCaseAdaptor.swift in Sources */, - 026A502C2D2F6CC3002C42C2 /* View+Measurements.swift in Sources */, 868029532C184E6C00CB64A1 /* BottomSheetProductCategory.swift in Sources */, B55BC1F121A878A30011A0C0 /* String+HTML.swift in Sources */, B56C721221B5B44000E5E85B /* PushNotificationsConfiguration.swift in Sources */, @@ -16627,7 +16569,6 @@ B9B0391A28A68ADE00DC1C83 /* ConstraintsUpdatingHostingController.swift in Sources */, B98D425B2AF9374400973C76 /* LargeHeightLeftImageTableViewCell.swift in Sources */, 0375799928201F750083F2E1 /* CardPresentPaymentsReadinessUseCase.swift in Sources */, - E10BC15E26CC06970064F5E2 /* ScrollableVStack.swift in Sources */, B50BB4162141828F00AF0F3C /* FooterSpinnerView.swift in Sources */, 867B330F2B4D39B900DCBEA6 /* BlazeAddParameterView.swift in Sources */, D8610CE2257099E100A5DF27 /* FancyAlertViewController+UnifiedLogin.swift in Sources */, @@ -16941,7 +16882,7 @@ DA24152B2D116EAE0008F69A /* WooShippingAddPackageViewModelTests.swift in Sources */, DE19BB1D26C6911900AB70D9 /* ShippingLabelCustomsFormListViewModelTests.swift in Sources */, D449C52C26E02F2F00D75B02 /* WhatsNewFactoryTests.swift in Sources */, - 687C006F2D6346E300F832FC /* POSCollectOrderPaymentAnalyticsTests.swift in Sources */, + 687C006F2D6346E300F832FC /* POSCollectOrderPaymentAnalyticsAdaptorTests.swift in Sources */, 5761298B24589B84007BB2D9 /* NumberFormatter+LocalizedOrNinetyNinePlusTests.swift in Sources */, EE19058A2B590FF800617C53 /* BlazePaymentMethodsViewModelTests.swift in Sources */, 2667BFD7252E5DBF008099D4 /* RefundItemViewModelTests.swift in Sources */, @@ -17223,7 +17164,6 @@ DEDA8D972B034C260076BF0F /* ProductSubscriptionPeriodPickerUseCaseTests.swift in Sources */, 02A275C623FE9EFC005C560F /* MockFeatureFlagService.swift in Sources */, DE2004782C05C36900660A72 /* MockInboxEligibilityChecker.swift in Sources */, - 31F635DC273AF0B100E14F10 /* VersionHelpersTests.swift in Sources */, EEADF626281A65A9001B40F1 /* DefaultShippingValueLocalizerTests.swift in Sources */, FE3E427726A8545B00C596CE /* MockRoleEligibilityUseCase.swift in Sources */, 02F67FF525806E0100C3BAD2 /* ShippingLabelTrackingURLGeneratorTests.swift in Sources */, @@ -17249,6 +17189,7 @@ 262EB5B3298D66FE009DCC36 /* SupportDataSourcesTests.swift in Sources */, 68A5221B2BA1804900A6A584 /* PluginDetailsViewModelTests.swift in Sources */, 0286837727B25930000E5785 /* HubMenuViewModelTests.swift in Sources */, + 01C230E92E3A334D00621DB0 /* MockOnboardingViewFactoryConfiguration.swift in Sources */, 02C7EE902B22EFB9008B7DF8 /* CollapsibleProductRowCardViewModelTests.swift in Sources */, CC0324A3263AD9F40056C6B7 /* MockShippingLabelAccountSettings.swift in Sources */, 453904F523BB8BD5007C4956 /* ProductTaxClassListSelectorDataSourceTests.swift in Sources */, @@ -17271,7 +17212,6 @@ 024A543622BA84DB00F4F38E /* DeveloperEmailCheckerTests.swift in Sources */, DE06D6602D64699D00419FFA /* AuthenticatedWebViewModelTests.swift in Sources */, B541B2132189E7FD008FE7C1 /* ScannerWooTests.swift in Sources */, - CC4B252D27CFE443008D2E6E /* OrderTotalsCalculatorTests.swift in Sources */, DEF8CF1A29AC6E5900800A60 /* AdminRoleRequiredViewModelTests.swift in Sources */, 02EAF5C329FA30FF0058071C /* ProductDescriptionGenerationViewModelTests.swift in Sources */, B57C5C9A21B80E7100FF82B2 /* DataWooTests.swift in Sources */, diff --git a/WooCommerce/WooCommerceTests/POS/Analytics/POSCollectOrderPaymentAnalyticsTests.swift b/WooCommerce/WooCommerceTests/POS/Adaptors/POSCollectOrderPaymentAnalyticsAdaptorTests.swift similarity index 90% rename from WooCommerce/WooCommerceTests/POS/Analytics/POSCollectOrderPaymentAnalyticsTests.swift rename to WooCommerce/WooCommerceTests/POS/Adaptors/POSCollectOrderPaymentAnalyticsAdaptorTests.swift index 616d33bc9ea..230ce6848c7 100644 --- a/WooCommerce/WooCommerceTests/POS/Analytics/POSCollectOrderPaymentAnalyticsTests.swift +++ b/WooCommerce/WooCommerceTests/POS/Adaptors/POSCollectOrderPaymentAnalyticsAdaptorTests.swift @@ -4,7 +4,7 @@ import struct Yosemite.CardPresentPaymentsConfiguration import enum WooFoundation.CountryCode import Testing -struct POSCollectOrderPaymentAnalyticsTests { +struct POSCollectOrderPaymentAnalyticsAdaptorTests { private let analytics: MockPOSAnalytics init() { @@ -15,7 +15,7 @@ struct POSCollectOrderPaymentAnalyticsTests { // Given let siteID: Int64 = 123 let configuration = CardPresentPaymentsConfiguration(country: .US) - let sut = POSCollectOrderPaymentAnalytics(analytics: analytics, configuration: configuration) + let sut = POSCollectOrderPaymentAnalyticsAdaptor(analytics: analytics, configuration: configuration) let capturedPaymentData = CardPresentCapturedPaymentData(paymentMethod: .cardPresent(details: .fake()), receiptParameters: nil) let expectedEvent = "card_present_collect_payment_success" let expectedProperties = [ diff --git a/WooCommerce/WooCommerceTests/POS/Mocks/MockOnboardingViewFactoryConfiguration.swift b/WooCommerce/WooCommerceTests/POS/Mocks/MockOnboardingViewFactoryConfiguration.swift new file mode 100644 index 00000000000..3ec1bd8321d --- /dev/null +++ b/WooCommerce/WooCommerceTests/POS/Mocks/MockOnboardingViewFactoryConfiguration.swift @@ -0,0 +1,9 @@ +import Foundation +import enum Yosemite.CardPresentPaymentOnboardingState +@testable import WooCommerce + +class MockOnboardingViewFactoryConfiguration: CardPresentPaymentsOnboardingViewConfiguration { + var showSupport: (() -> Void)? + var showURL: ((URL) -> Void)? + var state: CardPresentPaymentOnboardingState = .loading +} diff --git a/WooCommerce/WooCommerceTests/POS/Mocks/MockPointOfSaleAggregateModel.swift b/WooCommerce/WooCommerceTests/POS/Mocks/MockPointOfSaleAggregateModel.swift index be326bbffd0..d4b4955afb8 100644 --- a/WooCommerce/WooCommerceTests/POS/Mocks/MockPointOfSaleAggregateModel.swift +++ b/WooCommerce/WooCommerceTests/POS/Mocks/MockPointOfSaleAggregateModel.swift @@ -18,7 +18,7 @@ final class MockPointOfSaleAggregateModel: PointOfSaleAggregateModelProtocol { var cardPresentPaymentInlineMessage: WooCommerce.PointOfSaleCardPresentPaymentMessageType? - var cardPresentPaymentOnboardingViewModel: WooCommerce.CardPresentPaymentsOnboardingViewModel? + var cardPresentPaymentOnboardingViewFactory: WooCommerce.CardPresentPaymentOnboardingViewFactory? func cancelCardPaymentsOnboarding() { } diff --git a/WooCommerce/WooCommerceTests/POS/Models/PointOfSaleAggregateModelTests.swift b/WooCommerce/WooCommerceTests/POS/Models/PointOfSaleAggregateModelTests.swift index 70938ec74cd..ab572d28c03 100644 --- a/WooCommerce/WooCommerceTests/POS/Models/PointOfSaleAggregateModelTests.swift +++ b/WooCommerce/WooCommerceTests/POS/Models/PointOfSaleAggregateModelTests.swift @@ -746,25 +746,24 @@ struct PointOfSaleAggregateModelTests { // MARK: Onboarding @available(iOS 17.0, *) - @Test func cardPresentPaymentOnboardingViewModel_is_non_nil_when_onboarding_is_required() async throws { + @Test func cardPresentPaymentOnboardingViewFactory_is_non_nil_when_onboarding_is_required() async throws { // Given let itemsController = MockPointOfSaleItemsController() let sut = makePointOfSaleAggregateModel( itemsController: itemsController, cardPresentPaymentService: cardPresentPaymentService, orderController: orderController) - let onboardingViewModel = CardPresentPaymentsOnboardingViewModel( - fixedState: .pluginNotActivated(plugin: .stripe), - useCase: MockCardPresentPaymentsOnboardingUseCase(initial: .pluginNotActivated(plugin: .stripe)) - ) + let configuration = MockOnboardingViewFactoryConfiguration() + configuration.state = .pluginNotActivated(plugin: .stripe) + let factory = CardPresentPaymentOnboardingViewFactory.init(configuration: configuration) cardPresentPaymentService.paymentEvent = .idle - try #require(sut.cardPresentPaymentOnboardingViewModel == nil) + try #require(sut.cardPresentPaymentOnboardingViewFactory == nil) // When - cardPresentPaymentService.paymentEvent = .showOnboarding(onboardingViewModel: onboardingViewModel, onCancel: {}) + cardPresentPaymentService.paymentEvent = .showOnboarding(factory: factory, onCancel: {}) // Then - #expect(sut.cardPresentPaymentOnboardingViewModel?.state == .pluginNotActivated(plugin: .stripe)) + #expect(sut.cardPresentPaymentOnboardingViewFactory?.configuration.state == .pluginNotActivated(plugin: .stripe)) } @available(iOS 17.0, *) @@ -841,11 +840,11 @@ struct PointOfSaleAggregateModelTests { sut.addToCart(makePurchasableItem()) - let onboardingViewModel = CardPresentPaymentsOnboardingViewModel( - fixedState: .noConnectionError, - useCase: MockCardPresentPaymentsOnboardingUseCase(initial: .noConnectionError) - ) - cardPresentPaymentService.paymentEvent = .showOnboarding(onboardingViewModel: onboardingViewModel, onCancel: {}) + let configuration = MockOnboardingViewFactoryConfiguration() + configuration.state = .noConnectionError + let factory = CardPresentPaymentOnboardingViewFactory.init(configuration: configuration) + + cardPresentPaymentService.paymentEvent = .showOnboarding(factory: factory, onCancel: {}) // When sut.cancelCardPaymentsOnboarding() diff --git a/WooCommerce/WooCommerceTests/POS/Presentation/Payments Onboarding/PointOfSaleCardPresentPaymentOnboardingViewModelTests.swift b/WooCommerce/WooCommerceTests/POS/Presentation/Payments Onboarding/PointOfSaleCardPresentPaymentOnboardingViewModelTests.swift index 80a77f89f46..49db386fa37 100644 --- a/WooCommerce/WooCommerceTests/POS/Presentation/Payments Onboarding/PointOfSaleCardPresentPaymentOnboardingViewModelTests.swift +++ b/WooCommerce/WooCommerceTests/POS/Presentation/Payments Onboarding/PointOfSaleCardPresentPaymentOnboardingViewModelTests.swift @@ -1,11 +1,14 @@ import XCTest @testable import WooCommerce +import SwiftUI final class PointOfSaleCardPresentPaymentOnboardingViewModelTests: XCTestCase { func test_onDismissTap_is_invoked_when_cancelOnboarding_is_called() throws { // Given var isDismissTapInvoked = false - let sut = PointOfSaleCardPresentPaymentOnboardingViewModel(onboardingViewModel: .init(fixedState: .genericError), + let configuration = MockOnboardingViewFactoryConfiguration() + let sut = PointOfSaleCardPresentPaymentOnboardingViewModel( + onboardingViewFactory: .init(configuration: configuration), onDismissTap: { isDismissTapInvoked = true }) @@ -19,13 +22,15 @@ final class PointOfSaleCardPresentPaymentOnboardingViewModelTests: XCTestCase { func test_onboardingURL_is_set_when_onboarding_vm_showURL_is_invoked() throws { // Given - let onboardingViewModel = CardPresentPaymentsOnboardingViewModel(fixedState: .noConnectionError) - let sut = PointOfSaleCardPresentPaymentOnboardingViewModel(onboardingViewModel: onboardingViewModel, onDismissTap: nil) + let configuration = MockOnboardingViewFactoryConfiguration() + let sut = PointOfSaleCardPresentPaymentOnboardingViewModel( + onboardingViewFactory: .init(configuration: configuration), + onDismissTap: nil) XCTAssertNil(sut.onboardingURL) // When let url = try XCTUnwrap(URL(string: "https://example.com")) - onboardingViewModel.showURL?(url) + configuration.showURL?(url) // Then XCTAssertEqual(sut.onboardingURL, url)