Skip to content

Commit e3f2e94

Browse files
committed
Revert POSTabEligibilityChecker changes to be mostly the same as trunk. Will be modified to i2 in the next PR.
1 parent f3b84c8 commit e3f2e94

File tree

2 files changed

+101
-35
lines changed

2 files changed

+101
-35
lines changed

WooCommerce/Classes/POS/TabBar/POSIneligibleView.swift

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ struct POSIneligibleView: View {
7777

7878
private var suggestionText: String {
7979
switch reason {
80+
case .notTablet:
81+
return NSLocalizedString("pos.ineligible.suggestion.notTablet",
82+
value: "Please use a tablet to access POS features.",
83+
comment: "Suggestion for not tablet: use iPad")
8084
case .unsupportedIOSVersion:
8185
return NSLocalizedString("pos.ineligible.suggestion.unsupportedIOSVersion",
8286
value: "Point of Sale requires iOS 17 or later. Please update your device to iOS 17+ to use this feature.",
@@ -101,6 +105,16 @@ struct POSIneligibleView: View {
101105
return NSLocalizedString("pos.ineligible.suggestion.featureSwitchSyncFailure",
102106
value: "Try relaunching the app or check your internet connection and try again.",
103107
comment: "Suggestion for feature switch sync failure: relaunch or check connection")
108+
case let .unsupportedCountry(supportedCountries):
109+
let countryNames = supportedCountries.map { $0.readableCountry }
110+
let formattedCountryList = ListFormatter.localizedString(byJoining: countryNames)
111+
let format = NSLocalizedString(
112+
"pos.ineligible.suggestion.unsupportedCountry",
113+
value: "POS is currently only available in %1$@. Check back later for availability in your region.",
114+
comment: "Suggestion for unsupported country with list of supported countries. " +
115+
"%1$@ is a placeholder for the localized list of supported country names."
116+
)
117+
return String.localizedStringWithFormat(format, formattedCountryList)
104118
case let .unsupportedCurrency(supportedCurrencies):
105119
let currencyList = supportedCurrencies.map { $0.rawValue }
106120
let formattedCurrencyList = ListFormatter.localizedString(byJoining: currencyList)
@@ -116,6 +130,10 @@ struct POSIneligibleView: View {
116130
return NSLocalizedString("pos.ineligible.suggestion.siteSettingsNotAvailable",
117131
value: "Check your internet connection and try relaunching the app. If the issue persists, please contact support.",
118132
comment: "Suggestion for site settings unavailable: check connection or contact support")
133+
case .featureFlagDisabled:
134+
return NSLocalizedString("pos.ineligible.suggestion.featureFlagDisabled",
135+
value: "POS is currently disabled.",
136+
comment: "Suggestion for disabled feature flag: notify that POS is disabled remotely")
119137
case .selfDeallocated:
120138
return NSLocalizedString("pos.ineligible.suggestion.selfDeallocated",
121139
value: "Try relaunching the app to resolve this issue.",
@@ -158,6 +176,24 @@ private extension POSIneligibleView {
158176
}
159177
}
160178

179+
#Preview("Unsupported country") {
180+
if #available(iOS 17.0, *) {
181+
POSIneligibleView(
182+
reason: .unsupportedCountry(supportedCountries: [.US, .GB]),
183+
onRefresh: {}
184+
)
185+
}
186+
}
187+
188+
#Preview("Not a tablet") {
189+
if #available(iOS 17.0, *) {
190+
POSIneligibleView(
191+
reason: .notTablet,
192+
onRefresh: {}
193+
)
194+
}
195+
}
196+
161197
#Preview("Unsupported iOS version") {
162198
if #available(iOS 17.0, *) {
163199
POSIneligibleView(
@@ -176,6 +212,15 @@ private extension POSIneligibleView {
176212
}
177213
}
178214

215+
#Preview("Feature flag disabled") {
216+
if #available(iOS 17.0, *) {
217+
POSIneligibleView(
218+
reason: .featureFlagDisabled,
219+
onRefresh: {}
220+
)
221+
}
222+
}
223+
179224
#Preview("Feature switch disabled") {
180225
if #available(iOS 17.0, *) {
181226
POSIneligibleView(

WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/POSTabEligibilityChecker.swift

Lines changed: 56 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,15 @@ import class Yosemite.PluginsService
1717

1818
/// Represents the reasons why a site may be ineligible for POS.
1919
enum POSIneligibleReason: Equatable {
20+
case notTablet
2021
case unsupportedIOSVersion
2122
case unsupportedWooCommerceVersion(minimumVersion: String)
2223
case siteSettingsNotAvailable
2324
case wooCommercePluginNotFound
25+
case featureFlagDisabled
2426
case featureSwitchDisabled
2527
case featureSwitchSyncFailure
28+
case unsupportedCountry(supportedCountries: [CountryCode])
2629
case unsupportedCurrency(supportedCurrencies: [CurrencyCode])
2730
case selfDeallocated
2831
}
@@ -42,29 +45,10 @@ protocol POSEntryPointEligibilityCheckerProtocol {
4245
func checkEligibility() async -> POSEligibilityState
4346
}
4447

45-
/// Legacy enum containing POS invisible reasons + POSIneligibleReason cases for i1.
46-
private enum LegacyPOSIneligibleReason: Equatable {
47-
case notTablet
48-
case unsupportedIOSVersion
49-
case unsupportedWooCommerceVersion(minimumVersion: String)
50-
case siteSettingsNotAvailable
51-
case wooCommercePluginNotFound
52-
case featureFlagDisabled
53-
case featureSwitchDisabled
54-
case featureSwitchSyncFailure
55-
case unsupportedCountry(supportedCountries: [CountryCode])
56-
case unsupportedCurrency(supportedCurrencies: [CurrencyCode])
57-
case selfDeallocated
58-
}
59-
60-
/// Legacy POS eligibility state for i1.
61-
private enum LegacyPOSEligibilityState: Equatable {
62-
case eligible
63-
case ineligible(reason: LegacyPOSIneligibleReason)
64-
}
65-
66-
/// POS tab eligibility checker for i1. Will be replaced by `POSTabEligibilityCheckerI2` when removing `pointOfSaleAsATabi2` feature flag.
6748
final class POSTabEligibilityChecker: POSEntryPointEligibilityCheckerProtocol {
49+
private var siteSettingsEligibility: POSEligibilityState?
50+
private var featureFlagEligibility: POSEligibilityState?
51+
6852
private let siteID: Int64
6953
private let userInterfaceIdiom: UIUserInterfaceIdiom
7054
private let siteSettings: SelectedSiteSettingsProtocol
@@ -96,10 +80,6 @@ final class POSTabEligibilityChecker: POSEntryPointEligibilityCheckerProtocol {
9680

9781
/// Determines whether the POS entry point can be shown based on the selected store and feature gates.
9882
func checkEligibility() async -> POSEligibilityState {
99-
.eligible
100-
}
101-
102-
private func checkI1Eligibility() async -> LegacyPOSEligibilityState {
10383
switch checkDeviceEligibility() {
10484
case .eligible:
10585
break
@@ -138,13 +118,17 @@ final class POSTabEligibilityChecker: POSEntryPointEligibilityCheckerProtocol {
138118

139119
/// Checks the final visibility of the POS tab.
140120
func checkVisibility() async -> Bool {
141-
let eligibility = await checkI1Eligibility()
142-
return eligibility == .eligible
121+
if featureFlagService.isFeatureFlagEnabled(.pointOfSaleAsATabi2) {
122+
return await checkVisibilityBasedOnCountryAndRemoteFeatureFlag()
123+
} else {
124+
let eligibility = await checkEligibility()
125+
return eligibility == .eligible
126+
}
143127
}
144128
}
145129

146130
private extension POSTabEligibilityChecker {
147-
func checkDeviceEligibility() -> LegacyPOSEligibilityState {
131+
func checkDeviceEligibility() -> POSEligibilityState {
148132
guard #available(iOS 17.0, *) else {
149133
return .ineligible(reason: .unsupportedIOSVersion)
150134
}
@@ -155,12 +139,41 @@ private extension POSTabEligibilityChecker {
155139

156140
return .eligible
157141
}
142+
143+
func checkVisibilityBasedOnCountryAndRemoteFeatureFlag() async -> Bool {
144+
guard checkDeviceEligibility() == .eligible else {
145+
return false
146+
}
147+
148+
async let siteSettingsEligibility = checkSiteSettingsEligibility()
149+
async let featureFlagEligibility = checkRemoteFeatureEligibility()
150+
151+
self.siteSettingsEligibility = await siteSettingsEligibility
152+
switch await siteSettingsEligibility {
153+
case .eligible:
154+
break
155+
case let .ineligible(reason):
156+
if case .unsupportedCurrency = reason {
157+
break
158+
} else {
159+
return false
160+
}
161+
}
162+
163+
self.featureFlagEligibility = await featureFlagEligibility
164+
switch await featureFlagEligibility {
165+
case .eligible:
166+
return true
167+
case .ineligible:
168+
return false
169+
}
170+
}
158171
}
159172

160173
// MARK: - WC Plugin Related Eligibility Check
161174

162175
private extension POSTabEligibilityChecker {
163-
func checkPluginEligibility() async -> LegacyPOSEligibilityState {
176+
func checkPluginEligibility() async -> POSEligibilityState {
164177
let wcPlugin = await fetchWooCommercePlugin(siteID: siteID)
165178

166179
guard VersionHelpers.isVersionSupported(version: wcPlugin.version,
@@ -186,7 +199,7 @@ private extension POSTabEligibilityChecker {
186199
}
187200

188201
@MainActor
189-
func checkFeatureSwitchEnabled(siteID: Int64) async -> LegacyPOSEligibilityState {
202+
func checkFeatureSwitchEnabled(siteID: Int64) async -> POSEligibilityState {
190203
await withCheckedContinuation { [weak self] continuation in
191204
guard let self else {
192205
return continuation.resume(returning: .ineligible(reason: .selfDeallocated))
@@ -207,7 +220,11 @@ private extension POSTabEligibilityChecker {
207220
// MARK: - Site Settings Related Eligibility Check
208221

209222
private extension POSTabEligibilityChecker {
210-
func checkSiteSettingsEligibility() async -> LegacyPOSEligibilityState {
223+
func checkSiteSettingsEligibility() async -> POSEligibilityState {
224+
if let siteSettingsEligibility {
225+
return siteSettingsEligibility
226+
}
227+
211228
// Waits for the first site settings that matches the given site ID.
212229
let siteSettings = await waitForSiteSettingsRefresh()
213230
guard siteSettings.isNotEmpty else {
@@ -232,7 +249,7 @@ private extension POSTabEligibilityChecker {
232249
return []
233250
}
234251

235-
func isEligibleFromCountryAndCurrencyCode(countryCode: CountryCode, currencyCode: CurrencyCode) -> LegacyPOSEligibilityState {
252+
func isEligibleFromCountryAndCurrencyCode(countryCode: CountryCode, currencyCode: CurrencyCode) -> POSEligibilityState {
236253
let supportedCountries: [CountryCode] = [.US, .GB]
237254
let supportedCurrencies: [CountryCode: [CurrencyCode]] = [.US: [.USD],
238255
.GB: [.GBP]]
@@ -254,10 +271,14 @@ private extension POSTabEligibilityChecker {
254271

255272
private extension POSTabEligibilityChecker {
256273
@MainActor
257-
func checkRemoteFeatureEligibility() async -> LegacyPOSEligibilityState {
274+
func checkRemoteFeatureEligibility() async -> POSEligibilityState {
275+
if let featureFlagEligibility {
276+
return featureFlagEligibility
277+
}
278+
258279
// Only whitelisted accounts in WPCOM have the Point of Sale remote feature flag enabled. These can be found at D159901-code
259280
// If the account is whitelisted, then the remote value takes preference over the local feature flag configuration
260-
await withCheckedContinuation { [weak self] continuation in
281+
return await withCheckedContinuation { [weak self] continuation in
261282
guard let self else {
262283
return continuation.resume(returning: .ineligible(reason: .selfDeallocated))
263284
}

0 commit comments

Comments
 (0)