Skip to content

Commit ea2d1b5

Browse files
authored
[Woo POS] Improve card reader software update image (#15855)
2 parents bf9a4c0 + 36efecb commit ea2d1b5

12 files changed

+88
-43
lines changed

WooCommerce/Classes/POS/Presentation/Card Present Payments/Connection Alerts/PointOfSaleCardPresentPaymentOptionalReaderUpdateInProgressAlertViewModel.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ import SwiftUI
33

44
struct PointOfSaleCardPresentPaymentOptionalReaderUpdateInProgressAlertViewModel: Identifiable {
55
let title: String = Localization.title
6-
private let progress: Float
7-
let image: Image
6+
let progress: Float
87
let progressTitle: String
98
let progressSubtitle: String = Localization.messageOptional
109
let cancelButtonTitle: String
@@ -13,8 +12,11 @@ struct PointOfSaleCardPresentPaymentOptionalReaderUpdateInProgressAlertViewModel
1312
// This relies on the closures being immutable
1413
let id = UUID()
1514

15+
var isComplete: Bool {
16+
progress >= 1.0
17+
}
18+
1619
init(progress: Float, cancel: (() -> Void)?) {
17-
self.image = Image(uiImage: .posSoftwareUpdateProgress(progress: CGFloat(progress)))
1820
self.progress = progress
1921
self.progressTitle = String(format: Localization.percentCompleteFormat, 100 * progress)
2022

WooCommerce/Classes/POS/Presentation/Card Present Payments/Connection Alerts/PointOfSaleCardPresentPaymentReaderUpdateCompletionAlertViewModel.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import SwiftUI
33

44
struct PointOfSaleCardPresentPaymentReaderUpdateCompletionAlertViewModel {
55
let title: String = Localization.title
6-
let image: Image = .init(uiImage: .posSoftwareUpdateProgress(progress: CGFloat(1.0)))
76
let progressTitle: String = .init(format: Localization.percentCompleteFormat, 100.0)
87
}
98

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import SwiftUI
2+
3+
struct PointOfSaleCardPresentPaymentReaderUpdateProgressView: View {
4+
let progress: CGFloat
5+
let isComplete: Bool
6+
7+
var body: some View {
8+
ZStack {
9+
Circle()
10+
.fill(Color(.posSecondary))
11+
.frame(width: Constants.size, height: Constants.size)
12+
13+
Circle()
14+
.fill(Color(.posPrimary))
15+
.frame(width: Constants.size - Constants.borderInset, height: Constants.size - Constants.borderInset)
16+
.clipShape(
17+
Rectangle()
18+
.offset(y: (1 - progress) * Constants.size)
19+
)
20+
.animation(.easeOut(duration: 0.2), value: progress)
21+
22+
Image(uiImage: isComplete ? .cardReaderUpdateProgressCheckmark : .cardReaderUpdateProgressArrow)
23+
.renderingMode(.template)
24+
.foregroundColor(Color(.posOnPrimary))
25+
}
26+
.frame(width: Constants.size, height: Constants.size)
27+
}
28+
}
29+
30+
private enum Constants {
31+
static let size: CGFloat = 100
32+
static let borderInset: CGFloat = POSSpacing.xSmall
33+
}
34+
35+
@available(iOS 17.0, *)
36+
#Preview {
37+
@Previewable @State var progress: CGFloat = 0.5
38+
39+
VStack(spacing: 20) {
40+
PointOfSaleCardPresentPaymentReaderUpdateProgressView(progress: progress, isComplete: progress >= 1.0)
41+
Slider(value: $progress, in: 0...1)
42+
}
43+
.padding()
44+
}

WooCommerce/Classes/POS/Presentation/Card Present Payments/Connection Alerts/PointOfSaleCardPresentPaymentRequiredReaderUpdateInProgressAlertViewModel.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ import SwiftUI
33

44
struct PointOfSaleCardPresentPaymentRequiredReaderUpdateInProgressAlertViewModel: Identifiable {
55
let title: String = Localization.title
6-
private let progress: Float
7-
let image: Image
6+
let progress: Float
87
let progressTitle: String
98
let progressSubtitle: String = Localization.messageRequired
109
let cancelButtonTitle: String
@@ -13,8 +12,11 @@ struct PointOfSaleCardPresentPaymentRequiredReaderUpdateInProgressAlertViewModel
1312
// This relies on the closures being immutable
1413
let id = UUID()
1514

15+
var isComplete: Bool {
16+
progress >= 1.0
17+
}
18+
1619
init(progress: Float, cancel: (() -> Void)?) {
17-
self.image = Image(uiImage: .posSoftwareUpdateProgress(progress: CGFloat(progress)))
1820
self.progress = progress
1921
self.progressTitle = String(format: Localization.percentCompleteFormat, 100 * progress)
2022

WooCommerce/Classes/POS/Presentation/CardReaderConnection/UI States/Connection Alerts/PointOfSaleCardPresentPaymentOptionalReaderUpdateInProgressView.swift

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,12 @@ struct PointOfSaleCardPresentPaymentOptionalReaderUpdateInProgressView: View {
1414
VStack(spacing: PointOfSaleReaderConnectionModalLayout.contentButtonSpacing) {
1515
Spacer()
1616
VStack(spacing: PointOfSaleReaderConnectionModalLayout.imageTextSpacing) {
17-
viewModel.image
18-
.accessibilityHidden(true)
19-
.matchedGeometryEffect(id: animation.iconTransitionId, in: animation.namespace, properties: .position)
17+
PointOfSaleCardPresentPaymentReaderUpdateProgressView(
18+
progress: CGFloat(viewModel.progress),
19+
isComplete: viewModel.isComplete
20+
)
21+
.accessibilityHidden(true)
22+
.matchedGeometryEffect(id: animation.iconTransitionId, in: animation.namespace, properties: .position)
2023

2124
VStack(spacing: PointOfSaleReaderConnectionModalLayout.textSpacing) {
2225
Text(viewModel.title)
@@ -29,6 +32,7 @@ struct PointOfSaleCardPresentPaymentOptionalReaderUpdateInProgressView: View {
2932
Text(viewModel.progressTitle)
3033
.font(POSFontStyle.posBodyLargeRegular())
3134
.fixedSize(horizontal: false, vertical: true)
35+
.animation(nil, value: viewModel.progressTitle)
3236
Text(viewModel.progressSubtitle)
3337
.font(POSFontStyle.posBodyLargeRegular())
3438
.fixedSize(horizontal: false, vertical: true)

WooCommerce/Classes/POS/Presentation/CardReaderConnection/UI States/Connection Alerts/PointOfSaleCardPresentPaymentReaderUpdateCompletionView.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@ struct PointOfSaleCardPresentPaymentReaderUpdateCompletionView: View {
1212

1313
var body: some View {
1414
VStack(spacing: PointOfSaleReaderConnectionModalLayout.imageTextSpacing) {
15-
viewModel.image
16-
.accessibilityHidden(true)
17-
.matchedGeometryEffect(id: animation.iconTransitionId, in: animation.namespace, properties: .position)
15+
PointOfSaleCardPresentPaymentReaderUpdateProgressView(
16+
progress: 1,
17+
isComplete: true
18+
)
19+
.accessibilityHidden(true)
20+
.matchedGeometryEffect(id: animation.iconTransitionId, in: animation.namespace, properties: .position)
1821

1922
VStack(spacing: PointOfSaleReaderConnectionModalLayout.textSpacing) {
2023
Text(viewModel.title)

WooCommerce/Classes/POS/Presentation/CardReaderConnection/UI States/Connection Alerts/PointOfSaleCardPresentPaymentRequiredReaderUpdateInProgressView.swift

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,12 @@ struct PointOfSaleCardPresentPaymentRequiredReaderUpdateInProgressView: View {
1414
VStack(spacing: PointOfSaleReaderConnectionModalLayout.contentButtonSpacing) {
1515
Spacer()
1616
VStack(spacing: PointOfSaleReaderConnectionModalLayout.imageTextSpacing) {
17-
viewModel.image
18-
.accessibilityHidden(true)
19-
.matchedGeometryEffect(id: animation.iconTransitionId, in: animation.namespace, properties: .position)
17+
PointOfSaleCardPresentPaymentReaderUpdateProgressView(
18+
progress: CGFloat(viewModel.progress),
19+
isComplete: viewModel.isComplete
20+
)
21+
.accessibilityHidden(true)
22+
.matchedGeometryEffect(id: animation.iconTransitionId, in: animation.namespace, properties: .position)
2023

2124
VStack(spacing: PointOfSaleReaderConnectionModalLayout.textSpacing) {
2225
Text(viewModel.title)

WooCommerce/Classes/ViewRelated/ReusableViews/UpdateProgressImage.swift

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ extension UIImage {
88
}
99
let size = firstImage.size
1010
let rect = CGRect(origin: .zero, size: size)
11-
UIGraphicsBeginImageContext(size)
11+
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
1212

1313
for image in images {
1414
image.draw(in: rect)
@@ -28,7 +28,7 @@ extension UIImage {
2828

2929
let rect = CGRect(x: 0, y: 0, width: Constants.size, height: Constants.size)
3030
let clippingRect = CGRect(x: 0, y: (1 - progress) * Constants.size, width: Constants.size, height: Constants.size)
31-
UIGraphicsBeginImageContext(rect.size)
31+
UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
3232
defer { UIGraphicsEndImageContext() }
3333

3434
guard let context = UIGraphicsGetCurrentContext() else {
@@ -43,26 +43,16 @@ extension UIImage {
4343
}
4444

4545
static func softwareUpdateProgress(progress: CGFloat) -> UIImage {
46-
let symbol: UIImage = progress == 1 ? .cardReaderUpdateProgressCheckmark : .cardReaderUpdateProgressArrow
47-
48-
return .composite(images: [
49-
.cardReaderUpdateProgressBackground,
50-
.softwareUpdateProgressFill(progress: progress),
51-
symbol
52-
].compactMap { $0 }) ?? .init()
53-
}
54-
55-
static func posSoftwareUpdateProgress(progress: CGFloat) -> UIImage {
5646
let symbol: UIImage =
5747
progress == 1 ? .cardReaderUpdateProgressCheckmark : .cardReaderUpdateProgressArrow
5848
let backgroundImage = UIImage.cardReaderUpdateProgressBackground
5949
.withRenderingMode(.alwaysTemplate)
60-
.withTintColor(UIColor(.posSecondary))
50+
.withTintColor(.accent.withAlphaComponent(0.5))
6151
return .composite(
6252
images: [
6353
backgroundImage,
64-
.softwareUpdateProgressFill(progress: progress, fillColor: UIColor(.posPrimary)),
65-
symbol.withTintColor(UIColor(.posOnPrimary)),
54+
.softwareUpdateProgressFill(progress: progress, fillColor: .accent),
55+
symbol
6656
].compactMap { $0 }) ?? .init()
6757
}
6858
}
@@ -85,12 +75,6 @@ struct UpdateProgressImage_Previews: PreviewProvider {
8575
Image(uiImage: UIImage.softwareUpdateProgress(progress: complete))
8676
}
8777

88-
VStack {
89-
Text("POS Style")
90-
.font(.headline)
91-
Image(uiImage: UIImage.posSoftwareUpdateProgress(progress: complete))
92-
}
93-
9478
Slider(value: $complete, in: 0...1)
9579
}
9680
.padding()

WooCommerce/WooCommerce.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
013D2FB62CFF54BB00845D75 /* TapToPayEducationStepsFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 013D2FB52CFF54B600845D75 /* TapToPayEducationStepsFactory.swift */; };
3636
01435CF82DFC2CE800C0279B /* PointOfSaleInformationModal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01435CF72DFC2CE800C0279B /* PointOfSaleInformationModal.swift */; };
3737
014371272DFC8E2800C0279B /* PointOfSaleBarcodeScannerInformationModal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 014371262DFC8E2100C0279B /* PointOfSaleBarcodeScannerInformationModal.swift */; };
38+
014997222E1432AB002C50E1 /* PointOfSaleCardPresentPaymentReaderUpdateProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 014997212E1432AB002C50E1 /* PointOfSaleCardPresentPaymentReaderUpdateProgressView.swift */; };
3839
014BD4B82C64E2BA0011A66E /* PointOfSaleOrderSyncErrorMessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 014BD4B72C64E2BA0011A66E /* PointOfSaleOrderSyncErrorMessageView.swift */; };
3940
015456CE2DB0341D0071C3C4 /* POSPageHeaderActionButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 015456CD2DB033FF0071C3C4 /* POSPageHeaderActionButton.swift */; };
4041
0157A9962C4FEA7200866FFD /* PointOfSaleLoadingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0157A9952C4FEA7200866FFD /* PointOfSaleLoadingView.swift */; };
@@ -3187,6 +3188,7 @@
31873188
013D2FB52CFF54B600845D75 /* TapToPayEducationStepsFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TapToPayEducationStepsFactory.swift; sourceTree = "<group>"; };
31883189
01435CF72DFC2CE800C0279B /* PointOfSaleInformationModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PointOfSaleInformationModal.swift; sourceTree = "<group>"; };
31893190
014371262DFC8E2100C0279B /* PointOfSaleBarcodeScannerInformationModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PointOfSaleBarcodeScannerInformationModal.swift; sourceTree = "<group>"; };
3191+
014997212E1432AB002C50E1 /* PointOfSaleCardPresentPaymentReaderUpdateProgressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PointOfSaleCardPresentPaymentReaderUpdateProgressView.swift; sourceTree = "<group>"; };
31903192
014BD4B72C64E2BA0011A66E /* PointOfSaleOrderSyncErrorMessageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PointOfSaleOrderSyncErrorMessageView.swift; sourceTree = "<group>"; };
31913193
015456CD2DB033FF0071C3C4 /* POSPageHeaderActionButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = POSPageHeaderActionButton.swift; sourceTree = "<group>"; };
31923194
0157A9952C4FEA7200866FFD /* PointOfSaleLoadingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PointOfSaleLoadingView.swift; sourceTree = "<group>"; };
@@ -8135,6 +8137,7 @@
81358137
205B7EB52C19F89B00D14A36 /* Connection Alerts */ = {
81368138
isa = PBXGroup;
81378139
children = (
8140+
014997212E1432AB002C50E1 /* PointOfSaleCardPresentPaymentReaderUpdateProgressView.swift */,
81388141
203163BC2C1C9602001C96DA /* PointOfSaleCardPresentPaymentAlertType.swift */,
81398142
205B7EB82C19FAF700D14A36 /* PointOfSaleCardPresentPaymentScanningForReadersAlertViewModel.swift */,
81408143
205B7EBA2C19FB1200D14A36 /* PointOfSaleCardPresentPaymentScanningFailedAlertViewModel.swift */,
@@ -15766,6 +15769,7 @@
1576615769
B99B30CD2A85200D0066743D /* AddressFormViewModel.swift in Sources */,
1576715770
205E79462C204387001BA266 /* PointOfSaleCardPresentPaymentCancelledOnReaderMessageViewModel.swift in Sources */,
1576815771
029D025C2C231A1F00CB1E75 /* PointOfSaleCardPresentPaymentReaderUpdateCompletionAlertViewModel.swift in Sources */,
15772+
014997222E1432AB002C50E1 /* PointOfSaleCardPresentPaymentReaderUpdateProgressView.swift in Sources */,
1576915773
01620C4E2C5394B200D3EA2F /* POSProgressViewStyle.swift in Sources */,
1577015774
0196FF942DA8067A0063CEF1 /* CouponCardView.swift in Sources */,
1577115775
021125A52578E5730075AD2A /* BoldableTextView.swift in Sources */,

WooCommerce/WooCommerceTests/POS/Card Present Payments/Connection Alerts/PointOfSaleCardPresentPaymentOptionalReaderUpdateInProgressAlertViewModelTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ final class PointOfSaleCardPresentPaymentOptionalReaderUpdateInProgressAlertView
99
cancel: {})
1010

1111
XCTAssertPropertyCount(sut,
12-
expectedCount: 8,
12+
expectedCount: 7,
1313
messageHint: "Please check that the manual equatable conformance includes new properties.")
1414
}
1515

@@ -19,7 +19,7 @@ final class PointOfSaleCardPresentPaymentOptionalReaderUpdateInProgressAlertView
1919
cancel: {})
2020

2121
XCTAssertPropertyCount(sut,
22-
expectedCount: 8,
22+
expectedCount: 7,
2323
messageHint: "Please check that the manual hashable conformance includes new properties.")
2424
}
2525

0 commit comments

Comments
 (0)