Skip to content

Commit 4973930

Browse files
Merge branch 'release/10.5' into merge/10.4.1-hotfix-into-release-10.5
2 parents 10c8b7d + 73e494b commit 4973930

File tree

44 files changed

+1705
-571
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1705
-571
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
<!--
22
Contains editorialized release notes. Raw release notes should go into `RELEASE-NOTES.txt`.
33
-->
4+
## 10.5
5+
6+
This release includes a lot of exciting features! It's now possible to duplicate a product from the app. Just tap on the More Menu available inside the Product detail screen. We have also added a new stats widget so now you can view your current day's stats without opening the app. Lastly, due to popular demand, we're bringing back the ability to add/edit customer notes and addresses from the main order screen.
7+
8+
We welcome your feedback on the app, especially the new features we’re working on.
49

510
## 10.4
611

Experiments/Experiments/DefaultFeatureFlagService.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ public struct DefaultFeatureFlagService: FeatureFlagService {
3333
return true
3434
case .promptToEnableCodInIppOnboarding:
3535
return true
36+
case .orderCreationSearchCustomers:
37+
return buildConfig == .localDeveloper || buildConfig == .alpha
3638
default:
3739
return true
3840
}

Experiments/Experiments/FeatureFlag.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,8 @@ public enum FeatureFlag: Int {
6969
/// Whether to include the Cash on Delivery enable step in In-Person Payment onboarding
7070
///
7171
case promptToEnableCodInIppOnboarding
72+
73+
/// Enables the Search Customers functionality in the Order Creation screen
74+
///
75+
case orderCreationSearchCustomers
7276
}

Fakes/Fakes/Networking.generated.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,19 @@ extension DotcomError {
188188
.empty
189189
}
190190
}
191+
extension DotcomUser {
192+
/// Returns a "ready to use" type filled with fake values.
193+
///
194+
public static func fake() -> DotcomUser {
195+
.init(
196+
id: .fake(),
197+
username: .fake(),
198+
email: .fake(),
199+
displayName: .fake(),
200+
avatar: .fake()
201+
)
202+
}
203+
}
191204
extension InboxAction {
192205
/// Returns a "ready to use" type filled with fake values.
193206
///
@@ -220,6 +233,19 @@ extension InboxNote {
220233
)
221234
}
222235
}
236+
extension JetpackUser {
237+
/// Returns a "ready to use" type filled with fake values.
238+
///
239+
public static func fake() -> JetpackUser {
240+
.init(
241+
isConnected: .fake(),
242+
isPrimary: .fake(),
243+
username: .fake(),
244+
wpcomUser: .fake(),
245+
gravatar: .fake()
246+
)
247+
}
248+
}
223249
extension Leaderboard {
224250
/// Returns a "ready to use" type filled with fake values.
225251
///

Podfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ target 'WooCommerce' do
5252
pod 'Gridicons', '~> 1.2.0'
5353

5454
# To allow pod to pick up beta versions use -beta. E.g., 1.1.7-beta.1
55-
pod 'WordPressAuthenticator', '~> 3.1.0'
55+
pod 'WordPressAuthenticator', '~> 3.2.0'
5656
# pod 'WordPressAuthenticator', :git => 'https://github.com/wordpress-mobile/WordPressAuthenticator-iOS.git', :commit => ''
5757
# pod 'WordPressAuthenticator', :git => 'https://github.com/wordpress-mobile/WordPressAuthenticator-iOS.git', :branch => ''
5858
# pod 'WordPressAuthenticator', :path => '../WordPressAuthenticator-iOS'

Podfile.lock

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ PODS:
4242
- WordPress-Aztec-iOS (1.11.0)
4343
- WordPress-Editor-iOS (1.11.0):
4444
- WordPress-Aztec-iOS (= 1.11.0)
45-
- WordPressAuthenticator (3.1.0):
45+
- WordPressAuthenticator (3.2.0):
4646
- Alamofire (~> 4.8)
4747
- CocoaLumberjack (~> 3.5)
4848
- GoogleSignIn (~> 6.0.1)
@@ -92,7 +92,7 @@ DEPENDENCIES:
9292
- Sourcery (~> 1.0.3)
9393
- StripeTerminal (~> 2.7)
9494
- WordPress-Editor-iOS (~> 1.11.0)
95-
- WordPressAuthenticator (~> 3.1.0)
95+
- WordPressAuthenticator (~> 3.2.0)
9696
- WordPressKit (~> 4.49.0)
9797
- WordPressShared (~> 1.15)
9898
- WordPressUI (~> 1.12.5)
@@ -102,8 +102,6 @@ DEPENDENCIES:
102102
- ZendeskSupportSDK (~> 5.0)
103103

104104
SPEC REPOS:
105-
https://github.com/wordpress-mobile/cocoapods-specs.git:
106-
- WordPressAuthenticator
107105
trunk:
108106
- Alamofire
109107
- AppAuth
@@ -126,6 +124,7 @@ SPEC REPOS:
126124
- UIDeviceIdentifier
127125
- WordPress-Aztec-iOS
128126
- WordPress-Editor-iOS
127+
- WordPressAuthenticator
129128
- WordPressKit
130129
- WordPressShared
131130
- WordPressUI
@@ -163,7 +162,7 @@ SPEC CHECKSUMS:
163162
UIDeviceIdentifier: af4e11e25a2ea670078e2bd677bb0e8144f9f063
164163
WordPress-Aztec-iOS: 050b34d4c3adfb7c60363849049b13d60683b348
165164
WordPress-Editor-iOS: 304098424f1051cb271546c99f906aac296b1b81
166-
WordPressAuthenticator: 6e20b44d9743aa26e5089c16fbec35cd55748642
165+
WordPressAuthenticator: ee31d9b0420d2ab7a98e7fe931d3333bf97a47b2
167166
WordPressKit: 96deb6ba37ea5eaec4ddcaa53eca04d653246152
168167
WordPressShared: 5477f179c7fe03b5d574f91adda66f67d131827e
169168
WordPressUI: c5be816f6c7b3392224ac21de9e521e89fa108ac
@@ -179,6 +178,6 @@ SPEC CHECKSUMS:
179178
ZendeskSupportProvidersSDK: 2bdf8544f7cd0fd4c002546f5704b813845beb2a
180179
ZendeskSupportSDK: 3a8e508ab1d9dd22dc038df6c694466414e037ba
181180

182-
PODFILE CHECKSUM: a49b41520538bf9a2976016136166162186d972a
181+
PODFILE CHECKSUM: c6f79426669d379b37648d436ea6e799c3ac6fb2
183182

184183
COCOAPODS: 1.11.3

RELEASE-NOTES.txt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
*** PLEASE FOLLOW THIS FORMAT: [<priority indicator, more stars = higher priority>] <description> [<PR URL>]
22

3-
10.5
3+
10.6
44
-----
55

66

7+
10.5
8+
-----
9+
- [**] Products: Now you can duplicate products from the More menu of the product detail screen. [https://github.com/woocommerce/woocommerce-ios/pull/7727]
10+
- [**] Login: Added Jetpack connection support from the Account Mismatch error screen. [https://github.com/woocommerce/woocommerce-ios/pull/7748]
11+
- [*] Orders: We are bringing back the ability to add/edit customer notes and addresses from the main order screen [https://github.com/woocommerce/woocommerce-ios/pull/7750]
12+
- [*] Help center: Added help center web page with FAQs for "Wrong WordPress.com account error" screen. [https://github.com/woocommerce/woocommerce-ios/pull/7747]
13+
- [*] Widgets: The Today's Stat Widget adds support for bigger fonts. [https://github.com/woocommerce/woocommerce-ios/pull/7752]
14+
715
10.4
816
-----
917
- [***] Stats: Now you can add a Today's Stats Widget to your homescreen to monitor your sales. [https://github.com/woocommerce/woocommerce-ios/pull/7732]

WooCommerce/Classes/Analytics/WooAnalyticsStat.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,10 @@ public enum WooAnalyticsStat: String {
407407
case addProductSuccess = "add_product_success"
408408
case addProductFailed = "add_product_failed"
409409

410+
// MARK: Duplicate Product events
411+
case duplicateProductSuccess = "duplicate_product_success"
412+
case duplicateProductFailed = "duplicate_product_failed"
413+
410414
// MARK: Edit Product Events
411415
//
412416
case productDetailLoaded = "product_detail_loaded"
@@ -512,6 +516,7 @@ public enum WooAnalyticsStat: String {
512516
// MARK: Product Settings
513517
//
514518
case productDetailViewSettingsButtonTapped = "product_detail_view_settings_button_tapped"
519+
case productDetailDuplicateButtonTapped = "product_detail_duplicate_button_tapped"
515520
case productSettingsDoneButtonTapped = "product_settings_done_button_tapped"
516521
case productSettingsStatusTapped = "product_settings_status_tapped"
517522
case productSettingsVisibilityTapped = "product_settings_visibility_tapped"

WooCommerce/Classes/Authentication/AuthenticationManager.swift

Lines changed: 22 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -195,14 +195,8 @@ class AuthenticationManager: Authentication {
195195

196196
/// Account mismatched case
197197
guard matcher.match(originalURL: siteURL) else {
198-
/// Account mismatch experiment iteration 1: show jetpack connection error
199-
/// if the error happens during site credential login.
200-
if let credentials = credentials?.wporg {
201-
DDLogWarn("⚠️ Present Jetpack connection error for site: \(String(describing: siteURL))")
202-
return jetpackConnectionUI(for: siteURL, with: credentials, in: navigationController)
203-
}
204198
DDLogWarn("⚠️ Present account mismatch error for site: \(String(describing: siteURL))")
205-
return accountMismatchUI(for: siteURL, with: matcher)
199+
return accountMismatchUI(for: siteURL, siteCredentials: credentials?.wporg, with: matcher, in: navigationController)
206200
}
207201

208202
/// No Woo found
@@ -618,30 +612,29 @@ private extension AuthenticationManager {
618612
return ULErrorViewController(viewModel: viewModel)
619613
}
620614

621-
/// The error screen to be displayed when the user tries to enter as site
622-
/// whose Jetpack is not connected to their WP.com account.
623-
/// This screen is currently displayed when user logged in with site credentials.
624-
///
625-
func jetpackConnectionUI(for siteURL: String,
626-
with credentials: WordPressOrgCredentials,
627-
in navigationController: UINavigationController) -> UIViewController {
628-
let viewModel = JetpackConnectionErrorViewModel(siteURL: siteURL, credentials: credentials, onJetpackSetupCompletion: { email in
629-
return WordPressAuthenticator.showVerifyEmailForWPCom(
615+
/// The error screen to be displayed when the user tries to enter a site
616+
/// whose Jetpack is not associated with their account.
617+
/// - Parameters:
618+
/// - siteURL: URL for the site to log in to.
619+
/// - siteCredentials: WP.org credentials used to log in to the site if available.
620+
/// - matcher: the matcher used to check for matching sites.
621+
/// - navigationController: the controller that will present the view.
622+
///
623+
func accountMismatchUI(for siteURL: String,
624+
siteCredentials: WordPressOrgCredentials?,
625+
with matcher: ULAccountMatcher,
626+
in navigationController: UINavigationController) -> UIViewController {
627+
let viewModel = WrongAccountErrorViewModel(siteURL: siteURL,
628+
showsConnectedStores: matcher.hasConnectedStores,
629+
siteCredentials: siteCredentials,
630+
onJetpackSetupCompletion: { email, xmlrpc in
631+
WordPressAuthenticator.showVerifyEmailForWPCom(
630632
from: navigationController,
631-
xmlrpc: credentials.xmlrpc,
633+
xmlrpc: xmlrpc,
632634
connectedEmail: email,
633635
siteURL: siteURL
634636
)
635637
})
636-
return ULErrorViewController(viewModel: viewModel)
637-
}
638-
639-
/// The error screen to be displayed when the user tries to enter a site
640-
/// whose Jetpack is not associated with their account.
641-
/// This screen is currently displayed when user logged in with a WP.com account.
642-
///
643-
func accountMismatchUI(for siteURL: String, with matcher: ULAccountMatcher) -> UIViewController {
644-
let viewModel = WrongAccountErrorViewModel(siteURL: siteURL, showsConnectedStores: matcher.hasConnectedStores)
645638
let mismatchAccountUI = ULAccountMismatchViewController(viewModel: viewModel)
646639
return mismatchAccountUI
647640
}
@@ -682,15 +675,15 @@ private extension AuthenticationManager {
682675

683676
guard !site.isWPCom else {
684677
// The site doesn't belong to the current account since it was not included in the site picker.
685-
return accountMismatchUI(for: site.url, with: matcher)
678+
return accountMismatchUI(for: site.url, siteCredentials: nil, with: matcher, in: navigationController)
686679
}
687680

688681
/// Jetpack is required. Present an error if we don't detect a valid installation.
689-
guard site.isJetpackConnected == true else {
682+
guard site.isJetpackConnected else {
690683
return jetpackErrorUI(for: site.url, with: matcher, in: navigationController)
691684
}
692685

693-
return accountMismatchUI(for: site.url, with: matcher)
686+
return accountMismatchUI(for: site.url, siteCredentials: nil, with: matcher, in: navigationController)
694687
}
695688
}
696689

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import Foundation
2+
import WordPressAuthenticator
3+
4+
/// An interface used for mocking `WordPressAuthenticator` in unit tests.
5+
/// It's not complete for now since this is used for testing `WrongAccountErrorViewModel` only at the time of writing.
6+
/// Update this further if necessary.
7+
///
8+
protocol Authenticator {
9+
/// Used to present the site credential login flow directly from the delegate.
10+
///
11+
/// - Parameters:
12+
/// - presenter: The view controller that presents the site credential login flow.
13+
/// - siteURL: The URL of the site to log in to.
14+
/// - onCompletion: The closure to be trigged when the login succeeds with the input credentials.
15+
///
16+
static func showSiteCredentialLogin(from presenter: UIViewController, siteURL: String, onCompletion: @escaping (WordPressOrgCredentials) -> Void)
17+
18+
/// A helper method to fetch site info for a given URL.
19+
/// - Parameters:
20+
/// - siteURL: The URL of the site to fetch information for.
21+
/// - onCompletion: The closure to be triggered when fetching site info is done.
22+
///
23+
static func fetchSiteInfo(for siteURL: String, onCompletion: @escaping (Result<WordPressComSiteInfo, Error>) -> Void)
24+
}
25+
26+
/// Makes `WordPressAuthenticator` conform to the interface for mocking.
27+
///
28+
extension WordPressAuthenticator: Authenticator {}

0 commit comments

Comments
 (0)