Skip to content

Commit ccf9aad

Browse files
authored
Merge pull request #741 from woocommerce/issue/678-store-switcher-back
Store picker updates
2 parents b49abc0 + b600bbe commit ccf9aad

File tree

10 files changed

+393
-129
lines changed

10 files changed

+393
-129
lines changed

RELEASE-NOTES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
1.4
22
-----
3+
- improvement: The store switcher now allows you to go back to the previous screen without logging you out
34
- improvement: Custom order status labels are now supported! Instead of just displaying the order status slug and capitalizing the slug, the custom order status label will now be fetched from the server and properly displayed.
45
- improvement: Filtering by custom order status now supported!
56
- bugfix: correctly flips chevron on Dashboard > New Orders, to support RTL languages.

WooCommerce/Classes/AppDelegate.swift

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
5454
return window?.rootViewController as? MainTabBarController
5555
}
5656

57+
/// Store Picker Coordinator
58+
///
59+
private var storePickerCoordinator: StorePickerCoordinator?
60+
5761

5862
// MARK: - AppDelegate Methods
5963

@@ -343,17 +347,15 @@ extension AppDelegate {
343347
guard StoresManager.shared.isAuthenticated, StoresManager.shared.needsDefaultStore else {
344348
return
345349
}
350+
guard let tabBar = AppDelegate.shared.tabBarController,
351+
let navigationController = tabBar.selectedViewController as? UINavigationController else {
352+
DDLogError("⛔️ Unable to locate navigationController in order to launch the store picker.")
353+
return
354+
}
346355

347-
displayStorePicker()
348-
}
349-
350-
/// Displays the Woo Store Picker.
351-
///
352-
func displayStorePicker() {
353-
let pickerViewController = StorePickerViewController()
354-
let navigationController = UINavigationController(rootViewController: pickerViewController)
355-
356-
window?.rootViewController?.present(navigationController, animated: true, completion: nil)
356+
DDLogInfo("💬 Authenticated user does not have a Woo store selected — launching store picker.")
357+
storePickerCoordinator = StorePickerCoordinator(navigationController, config: .standard)
358+
storePickerCoordinator?.start()
357359
}
358360

359361
/// Whenever we're in an Authenticated state, let's Sync all of the WC-Y entities.

WooCommerce/Classes/Authentication/AuthenticationManager.swift

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@ import WordPressUI
44
import Yosemite
55

66

7-
87
/// Encapsulates all of the interactions with the WordPress Authenticator
98
///
109
class AuthenticationManager {
1110

11+
/// Store Picker Coordinator
12+
///
13+
private var storePickerCoordinator: StorePickerCoordinator?
14+
1215
/// Initializes the WordPress Authenticator.
1316
///
1417
func initialize() {
@@ -123,9 +126,9 @@ extension AuthenticationManager: WordPressAuthenticatorDelegate {
123126
/// Presents the Login Epilogue, in the specified NavigationController.
124127
///
125128
func presentLoginEpilogue(in navigationController: UINavigationController, for credentials: WordPressCredentials, onDismiss: @escaping () -> Void) {
126-
let pickerViewController = StorePickerViewController()
127-
pickerViewController.onDismiss = onDismiss
128-
navigationController.pushViewController(pickerViewController, animated: true)
129+
storePickerCoordinator = StorePickerCoordinator(navigationController, config: .login)
130+
storePickerCoordinator?.onDismiss = onDismiss
131+
storePickerCoordinator?.start()
129132
}
130133

131134
/// Presents the Signup Epilogue, in the specified NavigationController.

WooCommerce/Classes/Authentication/Epilogue/AccountHeaderView.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,16 @@ extension AccountHeaderView {
7474
}
7575
}
7676

77+
var isHelpButtonEnabled: Bool {
78+
set {
79+
helpButton.isHidden = !newValue
80+
helpButton.isEnabled = newValue
81+
}
82+
get {
83+
return helpButton.isHidden
84+
}
85+
}
86+
7787
/// Downloads (and displays) the Gravatar associated with the specified Email.
7888
///
7989
func downloadGravatar(with email: String) {
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
import Foundation
2+
import UIKit
3+
import Yosemite
4+
5+
6+
/// Simplifies and decouples the store picker from the caller
7+
///
8+
final class StorePickerCoordinator: Coordinator {
9+
10+
unowned var navigationController: UINavigationController
11+
12+
/// Determines how the store picker should initialized
13+
///
14+
var selectedConfiguration: StorePickerConfiguration
15+
16+
/// Closure to be executed upon dismissal of the store picker
17+
///
18+
var onDismiss: (() -> Void)?
19+
20+
/// Site Picker VC
21+
///
22+
private lazy var storePicker: StorePickerViewController = {
23+
let pickerVC = StorePickerViewController()
24+
pickerVC.delegate = self
25+
pickerVC.configuration = selectedConfiguration
26+
return pickerVC
27+
}()
28+
29+
init(_ navigationController: UINavigationController, config: StorePickerConfiguration) {
30+
self.navigationController = navigationController
31+
self.selectedConfiguration = config
32+
}
33+
34+
func start() {
35+
showStorePicker()
36+
}
37+
}
38+
39+
40+
// MARK: - StorePickerViewControllerDelegate Conformance
41+
//
42+
extension StorePickerCoordinator: StorePickerViewControllerDelegate {
43+
44+
func willSelectStore(with storeID: Int, onCompletion: @escaping SelectStoreClosure) {
45+
guard selectedConfiguration == .switchingStores else {
46+
onCompletion()
47+
return
48+
}
49+
guard storeID != StoresManager.shared.sessionManager.defaultStoreID else {
50+
onCompletion()
51+
return
52+
}
53+
54+
logOutOfCurrentStore(onCompletion: onCompletion)
55+
}
56+
57+
func didSelectStore(with storeID: Int) {
58+
guard storeID != StoresManager.shared.sessionManager.defaultStoreID else {
59+
return
60+
}
61+
62+
finalizeStoreSelection(storeID)
63+
presentStoreSwitchedNotice()
64+
onDismiss?()
65+
}
66+
}
67+
68+
// MARK: - Private Helpers
69+
//
70+
private extension StorePickerCoordinator {
71+
72+
func showStorePicker() {
73+
if selectedConfiguration == .standard {
74+
navigationController.present(storePicker, animated: true)
75+
} else {
76+
navigationController.pushViewController(storePicker, animated: true)
77+
}
78+
}
79+
80+
func presentStoreSwitchedNotice() {
81+
guard selectedConfiguration == .switchingStores else {
82+
return
83+
}
84+
guard let newStoreName = StoresManager.shared.sessionManager.defaultSite?.name else {
85+
return
86+
}
87+
88+
let message = NSLocalizedString("Switched to \(newStoreName). You will only receive notifications from this store.",
89+
comment: "Message presented after users switch to a new store. "
90+
+ "Reads like: Switched to {store name}. You will only receive notifications from this store.")
91+
let notice = Notice(title: message, feedbackType: .success)
92+
93+
AppDelegate.shared.noticePresenter.enqueue(notice: notice)
94+
}
95+
96+
func logOutOfCurrentStore(onCompletion: @escaping () -> Void) {
97+
StoresManager.shared.removeDefaultStore()
98+
99+
let group = DispatchGroup()
100+
101+
group.enter()
102+
let statsAction = StatsAction.resetStoredStats {
103+
group.leave()
104+
}
105+
StoresManager.shared.dispatch(statsAction)
106+
107+
group.enter()
108+
let orderAction = OrderAction.resetStoredOrders {
109+
group.leave()
110+
}
111+
StoresManager.shared.dispatch(orderAction)
112+
113+
group.notify(queue: .main) {
114+
onCompletion()
115+
}
116+
}
117+
118+
func finalizeStoreSelection(_ storeID: Int) {
119+
StoresManager.shared.updateDefaultStore(storeID: storeID)
120+
121+
// We need to call refreshUserData() here because the user selected
122+
// their default store and tracks should to know about it.
123+
WooAnalytics.shared.refreshUserData()
124+
WooAnalytics.shared.track(.sitePickerContinueTapped,
125+
withProperties: ["selected_store_id": StoresManager.shared.sessionManager.defaultStoreID ?? String()])
126+
127+
AppDelegate.shared.authenticatorWasDismissed()
128+
if selectedConfiguration == .login {
129+
MainTabBarController.switchToMyStoreTab(animated: true)
130+
}
131+
}
132+
}

0 commit comments

Comments
 (0)