Skip to content

Commit 233057b

Browse files
authored
[POS as a tab i2] Analytics & enable feature flag (#15918)
2 parents af9b54d + 5163038 commit 233057b

File tree

8 files changed

+77
-22
lines changed

8 files changed

+77
-22
lines changed

Modules/Sources/Experiments/DefaultFeatureFlagService.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ public struct DefaultFeatureFlagService: FeatureFlagService {
9696
case .pointOfSaleAsATabi1:
9797
return true
9898
case .pointOfSaleAsATabi2:
99-
return buildConfig == .localDeveloper || buildConfig == .alpha
99+
return true
100100
case .pointOfSaleOrdersi1:
101101
return true
102102
case .pointOfSaleOrdersi2:

RELEASE-NOTES.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
- [*] Shipping Labels: Improved VoiceOver accessibility [https://github.com/woocommerce/woocommerce-ios/pull/15912]
88
- [**] Order Details: Update Shipping Labels section for stores with Woo Shipping extension [https://github.com/woocommerce/woocommerce-ios/pull/15889]
99
- [*] Order List: New orders made through Point of Sale are now filterable via the Order List filters menu [https://github.com/woocommerce/woocommerce-ios/pull/15910]
10+
- [*] POS: a POS tab in the tab bar is now available in the app for stores in countries eligible for Point of Sale, instead of the tab is only shown when the store is eligible for POS. [https://github.com/woocommerce/woocommerce-ios/pull/15918]
1011
- [*] Shipping Labels: Display base rate on selected shipping service cards [https://github.com/woocommerce/woocommerce-ios/pull/15916]
1112
- [*] Shipping Labels: Update mark order completed toggle on purchase form [https://github.com/woocommerce/woocommerce-ios/pull/15917]
1213
- [internal] Optimized assets for app size reduction [https://github.com/woocommerce/woocommerce-ios/pull/15881]
@@ -795,7 +796,7 @@
795796
- [Internal] New default property `plan` is tracked in every event for logged-in users. [https://github.com/woocommerce/woocommerce-ios/pull/10356]
796797
- [Internal] Google sign in now defaults to bypassing the Google SDK [https://github.com/woocommerce/woocommerce-ios/pull/10341]
797798
- [*] Product list filter (Products tab and order creation > add products > filter): product types from extensions supported in the app are now available for product filtering - subscription, variable subscription, bundle, and composite. [https://github.com/woocommerce/woocommerce-ios/pull/10382]
798-
799+
799800
14.7
800801
-----
801802
- [*] Local notifications: Add a reminder to purchase a plan is scheduled 6hr after a free trial subscription. [https://github.com/woocommerce/woocommerce-ios/pull/10268]

WooCommerce/Classes/Analytics/WooAnalyticsStat.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,6 +1272,8 @@ enum WooAnalyticsStat: String {
12721272
// MARK: Point of Sale events
12731273
case pointOfSaleTabSelected = "main_tab_pos_selected"
12741274
case pointOfSaleTabVisibilityChecked = "pos_tab_visibility_checked"
1275+
case pointOfSaleIneligibleUIShown = "pos_ineligible_ui_shown"
1276+
case pointOfSaleIneligibleUIRetryTapped = "pos_ineligible_ui_retry_tapped"
12751277
case pointOfSaleLoaded = "loaded"
12761278
case pointOfSaleItemsFetched = "items_fetched"
12771279
case pointOfSaleItemsPullToRefresh = "items_pull_to_refresh"
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
extension WooAnalyticsEvent {
2+
enum PointOfSaleIneligibleUI {
3+
/// Event property key.
4+
private enum Key {
5+
static let reason = "reason"
6+
}
7+
8+
static func ineligibleUIShown(reason: POSIneligibleReason) -> WooAnalyticsEvent {
9+
WooAnalyticsEvent(statName: .pointOfSaleIneligibleUIShown, properties: [Key.reason: reason.analyticsValue])
10+
}
11+
12+
static func ineligibleUIRetryTapped(reason: POSIneligibleReason) -> WooAnalyticsEvent {
13+
WooAnalyticsEvent(statName: .pointOfSaleIneligibleUIRetryTapped, properties: [Key.reason: reason.analyticsValue])
14+
}
15+
}
16+
}
17+
18+
private extension POSIneligibleReason {
19+
var analyticsValue: String {
20+
switch self {
21+
case .unsupportedCurrency:
22+
return "store_currency"
23+
case .unsupportedWooCommerceVersion:
24+
return "wc_plugin_version"
25+
case .featureSwitchDisabled:
26+
return "feature_switch_disabled"
27+
case .wooCommercePluginNotFound:
28+
return "unknown_wc_plugin"
29+
case .unsupportedIOSVersion:
30+
return "ios_version"
31+
case .siteSettingsNotAvailable,
32+
.selfDeallocated:
33+
return "other"
34+
}
35+
}
36+
}
Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import SwiftUI
22

33
struct PointOfSaleLoadingView: View {
4-
@State private var waitingTimeTracker: WaitingTimeTracker?
5-
64
var body: some View {
75
HStack(alignment: .center) {
86
Spacer()
@@ -15,28 +13,10 @@ struct PointOfSaleLoadingView: View {
1513
.multilineTextAlignment(.center)
1614
Spacer()
1715
}
18-
.onAppear {
19-
trackTimeOnAppear()
20-
}
21-
.onDisappear {
22-
trackElapsedTimeOnDisappear()
23-
}
2416
.background(Color.posSurface)
2517
}
2618
}
2719

28-
private extension PointOfSaleLoadingView {
29-
func trackTimeOnAppear() {
30-
waitingTimeTracker = WaitingTimeTracker(trackScenario: .pointOfSaleLoaded)
31-
}
32-
33-
func trackElapsedTimeOnDisappear() {
34-
if let waitingTimeTracker = waitingTimeTracker {
35-
waitingTimeTracker.end(using: .milliseconds)
36-
}
37-
}
38-
}
39-
4020
#Preview {
4121
PointOfSaleLoadingView()
4222
}

WooCommerce/Classes/POS/Presentation/PointOfSaleDashboardView.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ struct PointOfSaleDashboardView: View {
88
@State private var showExitPOSModal: Bool = false
99
@State private var showSupport: Bool = false
1010
@State private var showDocumentation: Bool = false
11+
@State private var waitingTimeTracker: WaitingTimeTracker?
1112

1213
@State private var floatingSize: CGSize = .zero
1314

@@ -138,6 +139,14 @@ struct PointOfSaleDashboardView: View {
138139
}
139140
}
140141
.ignoresSafeArea(.keyboard)
142+
.onAppear {
143+
trackTimeForInitialLoadingState()
144+
}
145+
.onChange(of: viewState) { oldValue, newValue in
146+
if newValue == .content && oldValue != newValue {
147+
trackElapsedTimeForInitialLoadingState()
148+
}
149+
}
141150
}
142151

143152
private var contentView: some View {
@@ -210,6 +219,20 @@ private extension PointOfSaleDashboardView {
210219
}
211220
}
212221

222+
@available(iOS 17.0, *)
223+
private extension PointOfSaleDashboardView {
224+
func trackTimeForInitialLoadingState() {
225+
waitingTimeTracker = WaitingTimeTracker(trackScenario: .pointOfSaleLoaded)
226+
}
227+
228+
func trackElapsedTimeForInitialLoadingState() {
229+
if let waitingTimeTracker {
230+
waitingTimeTracker.end(using: .milliseconds)
231+
self.waitingTimeTracker = nil
232+
}
233+
}
234+
}
235+
213236
struct FloatingControlAreaSizeKey: EnvironmentKey {
214237
static let defaultValue = CGSize.zero
215238
}

WooCommerce/Classes/POS/TabBar/POSIneligibleView.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ struct POSIneligibleView: View {
4242
Task { @MainActor in
4343
do {
4444
isLoading = true
45+
ServiceLocator.analytics.track(
46+
event: .PointOfSaleIneligibleUI.ineligibleUIRetryTapped(reason: reason)
47+
)
4548
try await onRefresh()
4649
isLoading = false
4750
} catch {
@@ -71,6 +74,12 @@ struct POSIneligibleView: View {
7174
Spacer()
7275
}
7376
.padding(POSPadding.large)
77+
.onAppear {
78+
ServiceLocator.analytics.track(event: .PointOfSaleIneligibleUI.ineligibleUIShown(reason: reason))
79+
}
80+
.onChange(of: reason) { newReason in
81+
ServiceLocator.analytics.track(event: .PointOfSaleIneligibleUI.ineligibleUIShown(reason: newReason))
82+
}
7483
}
7584

7685
private var suggestionText: String {

WooCommerce/WooCommerce.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@
168168
02162727237963AF000208D2 /* ProductFormViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 02162725237963AF000208D2 /* ProductFormViewController.xib */; };
169169
02162729237965E8000208D2 /* ProductFormTableViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02162728237965E8000208D2 /* ProductFormTableViewModel.swift */; };
170170
0216272B2379662C000208D2 /* DefaultProductFormTableViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0216272A2379662C000208D2 /* DefaultProductFormTableViewModel.swift */; };
171+
0216DA702E2576CB00016600 /* WooAnalyticsEvent+PointOfSaleIneligibleUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0216DA6F2E2576C300016600 /* WooAnalyticsEvent+PointOfSaleIneligibleUI.swift */; };
171172
0218B4EC242E06F00083A847 /* MediaType+WPMediaType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0218B4EB242E06F00083A847 /* MediaType+WPMediaType.swift */; };
172173
0219B03723964527007DCD5E /* PaginatedProductShippingClassListSelectorDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0219B03623964527007DCD5E /* PaginatedProductShippingClassListSelectorDataSource.swift */; };
173174
021A17212D7036AF006DF7C0 /* DynamicFrameScaler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 021A17202D7036AF006DF7C0 /* DynamicFrameScaler.swift */; };
@@ -3345,6 +3346,7 @@
33453346
02162725237963AF000208D2 /* ProductFormViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ProductFormViewController.xib; sourceTree = "<group>"; };
33463347
02162728237965E8000208D2 /* ProductFormTableViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductFormTableViewModel.swift; sourceTree = "<group>"; };
33473348
0216272A2379662C000208D2 /* DefaultProductFormTableViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultProductFormTableViewModel.swift; sourceTree = "<group>"; };
3349+
0216DA6F2E2576C300016600 /* WooAnalyticsEvent+PointOfSaleIneligibleUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WooAnalyticsEvent+PointOfSaleIneligibleUI.swift"; sourceTree = "<group>"; };
33483350
0218B4EB242E06F00083A847 /* MediaType+WPMediaType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MediaType+WPMediaType.swift"; sourceTree = "<group>"; };
33493351
0219B03623964527007DCD5E /* PaginatedProductShippingClassListSelectorDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaginatedProductShippingClassListSelectorDataSource.swift; sourceTree = "<group>"; };
33503352
021A17202D7036AF006DF7C0 /* DynamicFrameScaler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DynamicFrameScaler.swift; sourceTree = "<group>"; };
@@ -7735,6 +7737,7 @@
77357737
02D1D2D82CD3CD710069A93F /* Analytics */ = {
77367738
isa = PBXGroup;
77377739
children = (
7740+
0216DA6F2E2576C300016600 /* WooAnalyticsEvent+PointOfSaleIneligibleUI.swift */,
77387741
68F68A4F2D6730DF00BB9568 /* POSCollectOrderPaymentAnalyticsTracking.swift */,
77397742
68F896412D5E4321000B308B /* POSCollectOrderPaymentAnalytics.swift */,
77407743
02D1D2D92CD3CD8D0069A93F /* WooAnalyticsEvent+PointOfSale.swift */,
@@ -16664,6 +16667,7 @@
1666416667
B59D1EE5219080B4009D1978 /* Note+Woo.swift in Sources */,
1666516668
02913E9523A774C500707A0C /* UnitInputFormatter.swift in Sources */,
1666616669
0204E3622B8CD40B00F1B5FD /* WooAnalyticsEvent+Products.swift in Sources */,
16670+
0216DA702E2576CB00016600 /* WooAnalyticsEvent+PointOfSaleIneligibleUI.swift in Sources */,
1666716671
4508BF622660E34A00707869 /* ShippingLabelCarrierAndRatesTopBanner.swift in Sources */,
1666816672
DE7E5E7F2B4BC52C002E28D2 /* MultiSelectionList.swift in Sources */,
1666916673
DA0DBE2F2C4FC61D00DF14C0 /* POSFloatingControlView.swift in Sources */,

0 commit comments

Comments
 (0)