Skip to content

Commit 8afe8d5

Browse files
committed
Merge branch 'trunk' into woomob-619-xcode-warnings-performing-io-on-the-main-thread-can-cause
2 parents 04c6e47 + 0c3d8be commit 8afe8d5

File tree

8 files changed

+268
-26
lines changed

8 files changed

+268
-26
lines changed

RELEASE-NOTES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
- [*] Fix initialization of authenticator to avoid crashes during login [https://github.com/woocommerce/woocommerce-ios/pull/15953]
88
- [*] Shipping Labels: Made HS tariff number field required in customs form for EU destinations [https://github.com/woocommerce/woocommerce-ios/pull/15946]
99
- [*] Order Details: Attempt to improve performance by using a simplified version of product objects. [https://github.com/woocommerce/woocommerce-ios/pull/15959]
10+
- [*] Order Creation: Prevent subscription products to be added to an order [https://github.com/woocommerce/woocommerce-ios/pull/15960]
1011
- [internal] Replace COTS_DEVICE reader model name with TAP_TO_PAY_DEVICE. [https://github.com/woocommerce/woocommerce-ios/pull/15961]
1112

1213
22.9

WooCommerce/Classes/POS/Models/Cart+BarcodeScanError.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,9 @@ extension PointOfSaleBarcodeScanError {
121121
)
122122

123123
static let incompleteScan = NSLocalizedString(
124-
"pointOfSale.barcodeScan.error.incompleteScan",
125-
value: "Partial barcode scan",
126-
comment: "Error message shown when scan is incomplete."
124+
"pointOfSale.barcodeScan.error.incompleteScan.2",
125+
value: "The scanner did not send an end-of-line character",
126+
comment: "Error message shown when scanner times out without sending end-of-line character."
127127
)
128128

129129
static let parsingError = NSLocalizedString(

WooCommerce/Classes/POS/Presentation/Barcode Scanning/GameControllerBarcodeParser.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ final class GameControllerBarcodeParser {
1515
private var buffer = ""
1616
private var lastKeyPressTime: Date?
1717
private var scanStartTime: Date?
18+
private var timeoutTimer: Timer?
1819

1920
init(configuration: HIDBarcodeParserConfiguration,
2021
onScan: @escaping (HIDBarcodeParserResult) -> Void,
@@ -49,6 +50,7 @@ final class GameControllerBarcodeParser {
4950
}
5051

5152
buffer.append(character)
53+
scheduleTimeoutTimer()
5254
}
5355
}
5456

@@ -186,6 +188,31 @@ final class GameControllerBarcodeParser {
186188
buffer = ""
187189
lastKeyPressTime = nil
188190
scanStartTime = nil
191+
cancelTimeoutTimer()
192+
}
193+
194+
private func scheduleTimeoutTimer() {
195+
cancelTimeoutTimer()
196+
timeoutTimer = timeProvider.scheduleTimer(
197+
timeInterval: configuration.maximumInterCharacterTime,
198+
target: self,
199+
selector: #selector(handleTimeoutExpiry)
200+
)
201+
}
202+
203+
private func cancelTimeoutTimer() {
204+
timeoutTimer?.invalidate()
205+
timeoutTimer = nil
206+
}
207+
208+
@objc private func handleTimeoutExpiry() {
209+
guard !buffer.isEmpty else { return }
210+
211+
let scanDurationMs = calculateScanDurationMs()
212+
let result = HIDBarcodeParserResult.failure(error: HIDBarcodeParserError.timedOut(barcode: buffer), scanDurationMs: scanDurationMs)
213+
214+
onScan(result)
215+
resetScan()
189216
}
190217

191218
private func calculateScanDurationMs() -> Int {
@@ -194,6 +221,7 @@ final class GameControllerBarcodeParser {
194221
}
195222

196223
private func processScan() {
224+
cancelTimeoutTimer()
197225
checkForTimeoutBetweenKeystrokes()
198226
let scanDurationMs = calculateScanDurationMs()
199227

WooCommerce/Classes/POS/Presentation/Barcode Scanning/TimeProvider.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,15 @@ import Foundation
22

33
protocol TimeProvider {
44
func now() -> Date
5+
func scheduleTimer(timeInterval: TimeInterval, target: Any, selector: Selector) -> Timer
56
}
67

78
struct DefaultTimeProvider: TimeProvider {
89
func now() -> Date {
910
Date()
1011
}
12+
13+
func scheduleTimer(timeInterval: TimeInterval, target: Any, selector: Selector) -> Timer {
14+
return Timer.scheduledTimer(timeInterval: timeInterval, target: target, selector: selector, userInfo: nil, repeats: false)
15+
}
1116
}

WooCommerce/Classes/ViewRelated/Products/ProductSelector/ProductSelectorView.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,16 +216,21 @@ struct ProductSelectorView: View {
216216
ProductRow(multipleSelectionsEnabled: true,
217217
viewModel: rowViewModel,
218218
onCheckboxSelected: {
219-
viewModel.variationCheckboxTapped(for: rowViewModel.productOrVariationID)
219+
if rowViewModel.selectionEnabled {
220+
viewModel.variationCheckboxTapped(for: rowViewModel.productOrVariationID)
221+
}
220222
})
221223
.frame(maxWidth: .infinity, alignment: .leading)
222224
.onTapGesture {
223-
viewModel.variationRowTapped(for: rowViewModel.productOrVariationID)
225+
if rowViewModel.selectionEnabled {
226+
viewModel.variationRowTapped(for: rowViewModel.productOrVariationID)
227+
}
224228
}
225229
.redacted(reason: viewModel.showPlaceholders ? .placeholder : [])
226230
.disabled(viewModel.selectionDisabled)
227231

228232
DisclosureIndicator()
233+
.renderedIf(rowViewModel.selectionEnabled)
229234
}
230235
.accessibilityHint(configuration.variableProductRowAccessibilityHint)
231236
} else {

WooCommerce/Classes/ViewRelated/Products/ProductSelector/ProductSelectorViewModel.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -848,6 +848,8 @@ private extension ProductSelectorViewModel {
848848
switch (source, product.productType, product.variations) {
849849
case (.orderForm, .booking, _):
850850
return .unsupported(reason: Localization.bookableProductUnsupportedReason)
851+
case (.orderForm, .subscription, _), (.orderForm, .variableSubscription, _):
852+
return .unsupported(reason: Localization.subscriptionProductUnsupportedReason)
851853
case (_, _, let variations) where variations.isEmpty:
852854
return selectedItemsIDs.contains(product.productID) ? .selected : .notSelected
853855
default:
@@ -981,6 +983,11 @@ private extension ProductSelectorViewModel {
981983
value: "Bookable products are not supported for order creation",
982984
comment: "Message explaining unsupported bookable products for order creation"
983985
)
986+
static let subscriptionProductUnsupportedReason = NSLocalizedString(
987+
"productSelectorViewModel.subscriptionProductUnsupportedReason",
988+
value: "Subscription products are not supported for order creation",
989+
comment: "Message explaining unsupported subscription products for order creation"
990+
)
984991
}
985992
}
986993

0 commit comments

Comments
 (0)