Skip to content

Commit 3eb3666

Browse files
Merge pull request #19824 from wordpress-mobile/merge/24.4.0.1-into-trunk
Merge 21.4.0.1 into trunk
2 parents 21e4fdb + 283e4b3 commit 3eb3666

File tree

56 files changed

+4664
-158
lines changed

Some content is hidden

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

56 files changed

+4664
-158
lines changed

RELEASE-NOTES.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
21.5
2+
-----
3+
4+
15
21.4
26
-----
37
* [*] Fixed an issue where publishing Posts and Pages could fail under certain conditions. [#19717]

WordPress/Classes/System/WordPressAppDelegate.swift

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -329,14 +329,19 @@ class WordPressAppDelegate: UIResponder, UIApplicationDelegate {
329329

330330
setupWordPressExtensions()
331331

332-
if FeatureFlag.contentMigration.enabled {
332+
if AppConfiguration.isWordPress,
333+
FeatureFlag.contentMigration.enabled {
333334
// To prevent race condition, initialize the shared instance synchronously so it can listen to account change notifications.
334335
let _ = ContentMigrationCoordinator.shared
335336

336-
// Start proactively exporting WP data in the background if the conditions are fulfilled.
337-
// This needs to be called after `setupWordPressExtensions` because it updates the stored data.
338-
DispatchQueue.global().async {
339-
ContentMigrationCoordinator.shared.startOnceIfNeeded()
337+
let launchUrl = launchOptions[.url] as? URL
338+
let exportUrl = URL(string: "\(AppScheme.wordpressMigrationV1.rawValue)\(WordPressExportRoute().path.removingPrefix("/"))")
339+
if launchUrl != exportUrl {
340+
// Start proactively exporting WP data in the background if the conditions are fulfilled.
341+
// This needs to be called after `setupWordPressExtensions` because it updates the stored data.
342+
DispatchQueue.global().async {
343+
ContentMigrationCoordinator.shared.startOnceIfNeeded()
344+
}
340345
}
341346
}
342347

WordPress/Classes/Utility/Migration/ContentMigrationCoordinator.swift

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,36 @@
66
.init()
77
}()
88

9+
var previousMigrationError: MigrationError? {
10+
guard let storedErrorValue = sharedPersistentRepository?.string(forKey: .exportErrorSharedKey) else {
11+
return nil
12+
}
13+
14+
return .init(rawValue: storedErrorValue)
15+
}
16+
917
// MARK: Dependencies
1018

1119
private let coreDataStack: CoreDataStack
1220
private let dataMigrator: ContentDataMigrating
1321
private let notificationCenter: NotificationCenter
1422
private let userPersistentRepository: UserPersistentRepository
23+
private let sharedPersistentRepository: UserPersistentRepository?
1524
private let eligibilityProvider: ContentMigrationEligibilityProvider
1625
private let tracker: MigrationAnalyticsTracker
1726

1827
init(coreDataStack: CoreDataStack = ContextManager.shared,
1928
dataMigrator: ContentDataMigrating = DataMigrator(),
2029
notificationCenter: NotificationCenter = .default,
2130
userPersistentRepository: UserPersistentRepository = UserDefaults.standard,
31+
sharedPersistentRepository: UserPersistentRepository? = UserDefaults(suiteName: WPAppGroupName),
2232
eligibilityProvider: ContentMigrationEligibilityProvider = AppConfiguration(),
2333
tracker: MigrationAnalyticsTracker = .init()) {
2434
self.coreDataStack = coreDataStack
2535
self.dataMigrator = dataMigrator
2636
self.notificationCenter = notificationCenter
2737
self.userPersistentRepository = userPersistentRepository
38+
self.sharedPersistentRepository = sharedPersistentRepository
2839
self.eligibilityProvider = eligibilityProvider
2940
self.tracker = tracker
3041

@@ -34,7 +45,7 @@
3445
ensureBackupDataDeletedOnLogout()
3546
}
3647

37-
enum ContentMigrationCoordinatorError: LocalizedError {
48+
enum MigrationError: String, LocalizedError {
3849
case ineligible
3950
case exportFailure
4051
case localDraftsNotSynced
@@ -58,30 +69,30 @@
5869
/// just let the user continue with the original intent in case of failure.
5970
///
6071
/// - Parameter completion: Closure called after the export process completes.
61-
func startAndDo(completion: ((Result<Void, ContentMigrationCoordinatorError>) -> Void)? = nil) {
72+
func startAndDo(completion: ((Result<Void, MigrationError>) -> Void)? = nil) {
6273
guard eligibilityProvider.isEligibleForMigration else {
6374
tracker.trackContentExportEligibility(eligible: false)
64-
completion?(.failure(.ineligible))
75+
processResult(.failure(.ineligible), completion: completion)
6576
return
6677
}
6778

6879
guard isLocalPostsSynced() else {
69-
let error = ContentMigrationCoordinatorError.localDraftsNotSynced
80+
let error = MigrationError.localDraftsNotSynced
7081
tracker.trackContentExportFailed(reason: error.localizedDescription)
71-
completion?(.failure(error))
82+
processResult(.failure(error), completion: completion)
7283
return
7384
}
7485

7586
dataMigrator.exportData { [weak self] result in
7687
switch result {
7788
case .success:
7889
self?.tracker.trackContentExportSucceeded()
79-
completion?(.success(()))
90+
self?.processResult(.success(()), completion: completion)
8091

8192
case .failure(let error):
8293
DDLogError("[Jetpack Migration] Error exporting data: \(error)")
8394
self?.tracker.trackContentExportFailed(reason: error.localizedDescription)
84-
completion?(.failure(.exportFailure))
95+
self?.processResult(.failure(.exportFailure), completion: completion)
8596
}
8697
}
8798
}
@@ -147,6 +158,11 @@ private extension ContentMigrationCoordinator {
147158
/// This prevents the user from entering the migration flow and immediately gets shown with a login pop-up (since we couldn't migrate the authToken anymore).
148159
///
149160
func ensureBackupDataDeletedOnLogout() {
161+
// we only need to listen to changes from the WordPress side.
162+
guard AppConfiguration.isWordPress else {
163+
return
164+
}
165+
150166
notificationCenter.addObserver(forName: .WPAccountDefaultWordPressComAccountChanged, object: nil, queue: nil) { [weak self] notification in
151167
// nil notification object means it's a logout event.
152168
guard let self,
@@ -157,6 +173,30 @@ private extension ContentMigrationCoordinator {
157173
self.cleanupExportedDataIfNeeded()
158174
}
159175
}
176+
177+
/// A "middleware" logic that attempts to record (or clear) any migration error to the App Group space
178+
/// before calling the completion block.
179+
///
180+
/// - Parameters:
181+
/// - result: The `Result` object from the export process.
182+
/// - completion: Closure that'll be executed after the process completes.
183+
func processResult(_ result: Result<Void, MigrationError>, completion: ((Result<Void, MigrationError>) -> Void)?) {
184+
// make sure that we're only intercepting from the WordPress side.
185+
guard AppConfiguration.isWordPress else {
186+
completion?(result)
187+
return
188+
}
189+
190+
switch result {
191+
case .success:
192+
sharedPersistentRepository?.removeObject(forKey: .exportErrorSharedKey)
193+
194+
case .failure(let error):
195+
sharedPersistentRepository?.set(error.rawValue, forKey: .exportErrorSharedKey)
196+
}
197+
198+
completion?(result)
199+
}
160200
}
161201

162202
// MARK: - Content Migration Eligibility Provider
@@ -176,4 +216,5 @@ extension AppConfiguration: ContentMigrationEligibilityProvider {
176216

177217
private extension String {
178218
static let oneOffMigrationKey = "wordpress_one_off_export"
219+
static let exportErrorSharedKey = "wordpress_shared_export_error"
179220
}

WordPress/Jetpack/Classes/System/JetpackWindowManager.swift

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ private extension JetpackWindowManager {
6464
MigrationAppDetection.getWordPressInstallationState() == .wordPressInstalledAndMigratable
6565
}
6666

67+
/// Checks whether the WordPress app has previously failed to export user content.
68+
var hasFailedExportAttempts: Bool {
69+
ContentMigrationCoordinator.shared.previousMigrationError != nil
70+
}
71+
6772
func sendMigrationEmail() {
6873
Task {
6974
let service = try? MigrationEmailService()
@@ -117,10 +122,21 @@ private extension JetpackWindowManager {
117122
self.show(loadWordPressViewController)
118123
}
119124

125+
/// Determine how to handle the error when the migration fails.
126+
///
127+
/// Show the loadWordPress path when:
128+
/// - A compatible WordPress app version exists,
129+
/// - There's no data to import, and
130+
/// - There's no data because the export was never triggered, not because WP tried to export and failed.
131+
///
132+
/// Otherwise, show the sign in flow.
133+
///
134+
/// - Parameter error: Error object from the data migration process.
120135
func handleMigrationFailure(_ error: DataMigrationError) {
121136
guard
122-
case .dataNotReadyToImport = error,
123137
isCompatibleWordPressAppPresent,
138+
case .dataNotReadyToImport = error,
139+
!hasFailedExportAttempts,
124140
let schemeUrl = URL(string: "\(AppScheme.wordpressMigrationV1.rawValue)\(WordPressExportRoute().path.removingPrefix("/"))")
125141
else {
126142
showSignInUI()

WordPress/Jetpack/Classes/Utility/DataMigrator.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ enum DataMigrationError: LocalizedError {
2020

2121
var errorDescription: String? {
2222
switch self {
23-
case .databaseCopyError: return "The database couldn't be copied from shared directory"
23+
case .databaseCopyError: return "The database couldn't be copied to/from shared directory"
2424
case .sharedUserDefaultsNil: return "Shared user defaults not found"
2525
case .dataNotReadyToImport: return "The data wasn't ready to import"
2626
}

WordPress/Jetpack/Classes/ViewRelated/WordPress-to-Jetpack Migration/Load WordPress/MigrationLoadWordPressViewModel.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ final class MigrationLoadWordPressViewModel {
4040
comment: "The description in the Load WordPress screen"
4141
)
4242
static let secondaryDescription = NSLocalizedString(
43-
"migration.loadWordpress.description",
43+
"migration.loadWordpress.secondaryDescription",
4444
value: "Would you like to transfer your data from the WordPress app and sign in automatically?",
4545
comment: "The secondary description in the Load WordPress screen"
4646
)

WordPress/Jetpack/Resources/release_notes.txt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1-
We fixed a small visual issue with the Home and Menu control in the My Site dashboard.
1+
* [*] Fixed an issue where publishing Posts and Pages could fail under certain conditions. [#19717]
2+
* [*] Share extension navigation bar is no longer transparent [#19700]
3+
* [***] [Jetpack-only] Adds a smooth, opt-in transition to the Jetpack app for users migrating from the WordPress app. [#19759]
4+
* [***] You can now migrate your site content to the Jetpack app without a hitch. [#19759]
5+
* [**] [internal] Upgrade React Native from 0.66.2 to 0.69.4 [https://github.com/wordpress-mobile/gutenberg-mobile/pull/5193]
6+
* [*] [internal] When a user migrates to the Jetpack app and allows notifications, WordPress app notifications are disabled. [#19616, #19611, #19590]
7+
* [*] Reader now scrolls to the top if the tab bar button is tapped. [#19769]
28

3-
We also squashed a bug in My Site. The "Disconnect from WordPress.com” button now disconnects when tapped and will refresh the app.

WordPress/JetpackDraftActionExtension/cs.lproj/InfoPlist.strings

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,10 @@
22
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
33
<!--Warning: Auto-generated file, do not edit.-->
44
<plist version="1.0">
5-
<dict/>
5+
<dict>
6+
<key>CFBundleDisplayName</key>
7+
<string>Uložit do Jetpacku</string>
8+
<key>CFBundleName</key>
9+
<string>Uložit do Jetpacku</string>
10+
</dict>
611
</plist>

WordPress/JetpackDraftActionExtension/pl.lproj/InfoPlist.strings

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,10 @@
22
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
33
<!--Warning: Auto-generated file, do not edit.-->
44
<plist version="1.0">
5-
<dict/>
5+
<dict>
6+
<key>CFBundleDisplayName</key>
7+
<string>Zapisz w Jetpack</string>
8+
<key>CFBundleName</key>
9+
<string>Zapisz w Jetpacku</string>
10+
</dict>
611
</plist>

0 commit comments

Comments
 (0)