diff --git a/Podfile.lock b/Podfile.lock index 17c8a7c3e3ad..9b4b4259a9ba 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -58,7 +58,7 @@ PODS: - Sodium (0.9.1) - Starscream (3.0.6) - SVProgressHUD (2.2.5) - - SwiftLint (0.53.0) + - SwiftLint (0.54.0) - UIDeviceIdentifier (2.3.0) - WordPress-Aztec-iOS (1.19.9) - WordPress-Editor-iOS (1.19.9): @@ -130,6 +130,7 @@ SPEC REPOS: https://github.com/wordpress-mobile/cocoapods-specs.git: - WordPressAuthenticator - WordPressKit + - WordPressShared trunk: - Alamofire - AlamofireImage @@ -158,7 +159,6 @@ SPEC REPOS: - UIDeviceIdentifier - WordPress-Aztec-iOS - WordPress-Editor-iOS - - WordPressShared - WordPressUI - wpxmlrpc - ZendeskCommonUISDK @@ -208,13 +208,13 @@ SPEC CHECKSUMS: Sodium: 23d11554ecd556196d313cf6130d406dfe7ac6da Starscream: ef3ece99d765eeccb67de105bfa143f929026cf5 SVProgressHUD: 1428aafac632c1f86f62aa4243ec12008d7a51d6 - SwiftLint: 5ce4d6a8ff83f1b5fd5ad5dbf30965d35af65e44 + SwiftLint: c1de071d9d08c8aba837545f6254315bc900e211 UIDeviceIdentifier: 442b65b4ff1832d4ca9c2a157815cb29ad981b17 WordPress-Aztec-iOS: fbebd569c61baa252b3f5058c0a2a9a6ada686bb WordPress-Editor-iOS: bda9f7f942212589b890329a0cb22547311749ef WordPressAuthenticator: e3c18f1b63222742a565fea3faf1a55a144ce8c4 WordPressKit: 57712035a44595cf49b0c9f0ad5b8b899a8cbe6a - WordPressShared: f99faa127509b666d2f8b931989a900e2fd9d10d + WordPressShared: cad7777b283d3ce2752f283df587342a581cd49b WordPressUI: a491454affda3b0fb812812e637dc5e8f8f6bd06 wpxmlrpc: 68db063041e85d186db21f674adf08d9c70627fd ZendeskCommonUISDK: 5f0a83f412e07ae23701f18c412fe783b3249ef5 diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt index 69aa345d5390..ec9570c7d385 100644 --- a/RELEASE-NOTES.txt +++ b/RELEASE-NOTES.txt @@ -1,6 +1,9 @@ 24.2 ----- +24.0.1 +----- +* [**] Fix crash when RichText values are not defined [https://github.com/wordpress-mobile/gutenberg-mobile/pull/6563] 24.1 ----- @@ -19,6 +22,8 @@ * [*] [internal] Drop iOS 14 Support: Remove deprecated UIDocumentPickerViewController API [#22286] * [***] [internal] Refactor WP.com sign in API requests [#22421] * [*] Add In-App Feedback Prompt. [#22050] +* [**] Disabled the ability of creating new Story posts. [#22453] +* [**] Disabled Story block [#22449] 24.0 ----- diff --git a/WordPress/Classes/Models/Blog.m b/WordPress/Classes/Models/Blog.m index 167ea5bb053f..33e1faff8e6d 100644 --- a/WordPress/Classes/Models/Blog.m +++ b/WordPress/Classes/Models/Blog.m @@ -707,9 +707,7 @@ - (BOOL)supportsPluginManagement - (BOOL)supportsStories { - BOOL hasRequiredJetpack = [self hasRequiredJetpackVersion:@"9.1"]; - // Stories are disabled in iPad until this Kanvas issue is solved: https://github.com/tumblr/kanvas-ios/issues/104 - return (hasRequiredJetpack || self.isHostedAtWPcom) && ![UIDevice isPad] && [JetpackFeaturesRemovalCoordinator jetpackFeaturesEnabled]; + return NO; } - (BOOL)supportsContactInfo diff --git a/WordPress/Classes/Services/MediaHelper.swift b/WordPress/Classes/Services/MediaHelper.swift index 7c582c6005ba..4beb471de0c3 100644 --- a/WordPress/Classes/Services/MediaHelper.swift +++ b/WordPress/Classes/Services/MediaHelper.swift @@ -67,38 +67,6 @@ class MediaHelper: NSObject { } } - - static func advertiseImageOptimization(completion: @escaping (() -> Void)) { - guard MediaSettings().advertiseImageOptimization else { - completion() - return - } - - let title = NSLocalizedString("appSettings.optimizeImagesPopup.title", value: "Keep optimizing images?", - comment: "Title of an alert informing users to enable image optimization in uploads.") - let message = NSLocalizedString("appSettings.optimizeImagesPopup.message", value: "Image optimization shrinks images for faster uploading.\n\nThis option is enabled by default, but you can change it in the app settings at any time.", - comment: "Message of an alert informing users to enable image optimization in uploads.") - let turnOffTitle = NSLocalizedString("appSettings.optimizeImagesPopup.turnOff", value: "No, turn off", comment: "Title of button for turning off image optimization, displayed in the alert informing users to enable image optimization in uploads.") - let leaveOnTitle = NSLocalizedString("appSettings.optimizeImagesPopup.turnOn", value: "Yes, leave on", comment: "Title of button for leaving on image optimization, displayed in the alert informing users to enable image optimization in uploads.") - - let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) - let turnOffAction = UIAlertAction(title: turnOffTitle, style: .default) { _ in - MediaSettings().imageOptimizationEnabled = false - WPAnalytics.track(.appSettingsOptimizeImagesPopupTapped, properties: ["option": "off"]) - completion() - } - let leaveOnAction = UIAlertAction(title: leaveOnTitle, style: .default) { _ in - MediaSettings().imageOptimizationEnabled = true - WPAnalytics.track(.appSettingsOptimizeImagesPopupTapped, properties: ["option": "on"]) - completion() - } - alert.addAction(turnOffAction) - alert.addAction(leaveOnAction) - alert.preferredAction = leaveOnAction - alert.presentFromRootViewController() - - MediaSettings().advertiseImageOptimization = false - } } extension Media { diff --git a/WordPress/Classes/Services/MediaSettings.swift b/WordPress/Classes/Services/MediaSettings.swift index 8b01674c3d3b..181c57fd342c 100644 --- a/WordPress/Classes/Services/MediaSettings.swift +++ b/WordPress/Classes/Services/MediaSettings.swift @@ -8,7 +8,6 @@ class MediaSettings: NSObject { fileprivate let imageQualityKey = "SavedImageQualitySetting" fileprivate let removeLocationKey = "SavedRemoveLocationSetting" fileprivate let maxVideoSizeKey = "SavedMaxVideoSizeSetting" - fileprivate let advertiseImageOptimizationKey = "SavedAdvertiseImageOptimization" fileprivate let defaultImageOptimization = true fileprivate let defaultMaxImageDimension = 2000 @@ -209,11 +208,6 @@ class MediaSettings: NSObject { } set { database.set(newValue, forKey: imageOptimizationKey) - - // If the user changes this setting manually, we disable the image optimization popup. - if advertiseImageOptimization { - advertiseImageOptimization = false - } } } @@ -229,17 +223,4 @@ class MediaSettings: NSObject { database.set(newValue.rawValue, forKey: imageQualityKey) } } - - var advertiseImageOptimization: Bool { - get { - if let savedAdvertiseImageOptimization = database.object(forKey: advertiseImageOptimizationKey) as? Bool { - return savedAdvertiseImageOptimization - } else { - return true - } - } - set { - database.set(newValue, forKey: advertiseImageOptimizationKey) - } - } } diff --git a/WordPress/Classes/Utility/Analytics/WPAnalyticsEvent.swift b/WordPress/Classes/Utility/Analytics/WPAnalyticsEvent.swift index 23b4b5b5d5bd..367ccb2cb526 100644 --- a/WordPress/Classes/Utility/Analytics/WPAnalyticsEvent.swift +++ b/WordPress/Classes/Utility/Analytics/WPAnalyticsEvent.swift @@ -320,7 +320,6 @@ import Foundation case appSettingsClearSpotlightIndexTapped case appSettingsClearSiriSuggestionsTapped case appSettingsOpenDeviceSettingsTapped - case appSettingsOptimizeImagesPopupTapped // Notifications case notificationsPreviousTapped @@ -1111,8 +1110,6 @@ import Foundation return "app_settings_max_image_size_changed" case .appSettingsImageQualityChanged: return "app_settings_image_quality_changed" - case .appSettingsOptimizeImagesPopupTapped: - return "app_settings_optimize_images_popup_tapped" // Account Close case .accountCloseTapped: diff --git a/WordPress/Classes/ViewRelated/Blog/Blog Details/Detail Header/BlogDetailHeaderView.swift b/WordPress/Classes/ViewRelated/Blog/Blog Details/Detail Header/BlogDetailHeaderView.swift index b9526c62c861..b0a4deb116a5 100644 --- a/WordPress/Classes/ViewRelated/Blog/Blog Details/Detail Header/BlogDetailHeaderView.swift +++ b/WordPress/Classes/ViewRelated/Blog/Blog Details/Detail Header/BlogDetailHeaderView.swift @@ -119,9 +119,9 @@ class BlogDetailHeaderView: UIView { assert(delegate != nil) if let siteActionsMenu = delegate?.makeSiteActionsMenu() { - titleView.siteActionButton.showsMenuAsPrimaryAction = true - titleView.siteActionButton.menu = siteActionsMenu - titleView.siteActionButton.addAction(UIAction { _ in + titleView.siteSwitcherButton.menu = siteActionsMenu + titleView.siteSwitcherButton.addTarget(self, action: #selector(siteSwitcherTapped), for: .touchUpInside) + titleView.siteSwitcherButton.addAction(UIAction { _ in WPAnalytics.trackEvent(.mySiteHeaderMoreTapped) }, for: .menuActionTriggered) } @@ -214,7 +214,7 @@ extension BlogDetailHeaderView { let stackView = UIStackView(arrangedSubviews: [ siteIconView, titleStackView, - siteActionButton + siteSwitcherButton ]) stackView.alignment = .center @@ -280,9 +280,9 @@ extension BlogDetailHeaderView { return button }() - let siteActionButton: UIButton = { + let siteSwitcherButton: UIButton = { let button = UIButton(frame: .zero) - let image = UIImage(named: "more-horizontal-mobile")?.withRenderingMode(.alwaysTemplate) + let image = UIImage(named: "chevron-down-slim")?.withRenderingMode(.alwaysTemplate) button.setImage(image, for: .normal) button.contentMode = .center @@ -290,7 +290,7 @@ extension BlogDetailHeaderView { button.tintColor = .secondaryLabel button.accessibilityLabel = NSLocalizedString("mySite.siteActions.button", value: "Site Actions", comment: "Button that reveals more site actions") button.accessibilityHint = NSLocalizedString("mySite.siteActions.hint", value: "Tap to show more site actions", comment: "Accessibility hint for button used to show more site actions") - button.accessibilityIdentifier = .siteActionAccessibilityId + button.accessibilityIdentifier = .switchSiteAccessibilityId return button }() @@ -359,8 +359,8 @@ extension BlogDetailHeaderView { private func setupConstraintsForSiteSwitcher() { NSLayoutConstraint.activate([ - siteActionButton.heightAnchor.constraint(equalToConstant: Dimensions.siteSwitcherHeight), - siteActionButton.widthAnchor.constraint(equalToConstant: Dimensions.siteSwitcherWidth) + siteSwitcherButton.heightAnchor.constraint(equalToConstant: Dimensions.siteSwitcherHeight), + siteSwitcherButton.widthAnchor.constraint(equalToConstant: Dimensions.siteSwitcherWidth) ]) } } @@ -370,7 +370,7 @@ private extension String { // MARK: Accessibility Identifiers static let siteTitleAccessibilityId = "site-title-button" static let siteUrlAccessibilityId = "site-url-button" - static let siteActionAccessibilityId = "site-action-button" + static let switchSiteAccessibilityId = "switch-site-button" } private enum Strings { diff --git a/WordPress/Classes/ViewRelated/Blog/Site Picker/SitePickerViewController+SiteActions.swift b/WordPress/Classes/ViewRelated/Blog/Site Picker/SitePickerViewController+SiteActions.swift index 26a3afaf38f0..b40c0dee66f5 100644 --- a/WordPress/Classes/ViewRelated/Blog/Site Picker/SitePickerViewController+SiteActions.swift +++ b/WordPress/Classes/ViewRelated/Blog/Site Picker/SitePickerViewController+SiteActions.swift @@ -65,7 +65,7 @@ extension SitePickerViewController { } let viewController = UIActivityViewController(activityItems: [url], applicationActivities: nil) if let popover = viewController.popoverPresentationController { - popover.sourceView = blogDetailHeaderView.titleView.siteActionButton + popover.sourceView = blogDetailHeaderView.titleView.siteSwitcherButton } present(viewController, animated: true, completion: nil) WPAnalytics.trackEvent(.mySiteHeaderShareSiteTapped) @@ -83,7 +83,7 @@ extension SitePickerViewController { return } - showAddSiteActionSheet(from: blogDetailHeaderView.titleView.siteActionButton, + showAddSiteActionSheet(from: blogDetailHeaderView.titleView.siteSwitcherButton, canCreateWPComSite: canCreateWPComSite, canAddSelfHostedSite: canAddSelfHostedSite) diff --git a/WordPress/Classes/ViewRelated/Gutenberg/GutenbergMediaPickerHelper.swift b/WordPress/Classes/ViewRelated/Gutenberg/GutenbergMediaPickerHelper.swift index dea27f2a5e9b..f3622b3563d6 100644 --- a/WordPress/Classes/ViewRelated/Gutenberg/GutenbergMediaPickerHelper.swift +++ b/WordPress/Classes/ViewRelated/Gutenberg/GutenbergMediaPickerHelper.swift @@ -62,10 +62,8 @@ extension GutenbergMediaPickerHelper: ImagePickerControllerDelegate { switch mediaType { case UTType.image.identifier: if let image = info[.originalImage] as? UIImage { - MediaHelper.advertiseImageOptimization() { [self] in - self.didPickMediaCallback?([image]) - self.didPickMediaCallback = nil - } + self.didPickMediaCallback?([image]) + self.didPickMediaCallback = nil } case UTType.movie.identifier: @@ -103,16 +101,7 @@ extension GutenbergMediaPickerHelper: PHPickerViewControllerDelegate { return } - let mediaFilter = picker.configuration.filter - if mediaFilter == PHPickerFilter(.all) || mediaFilter == PHPickerFilter(.image) { - MediaHelper.advertiseImageOptimization() { [self] in - didPickMediaCallback?(results.map(\.itemProvider)) - didPickMediaCallback = nil - } - } - else { - didPickMediaCallback?(results.map(\.itemProvider)) - didPickMediaCallback = nil - } + didPickMediaCallback?(results.map(\.itemProvider)) + didPickMediaCallback = nil } } diff --git a/WordPress/Classes/ViewRelated/Media/SiteMedia/Controllers/SiteMediaAddMediaMenuController.swift b/WordPress/Classes/ViewRelated/Media/SiteMedia/Controllers/SiteMediaAddMediaMenuController.swift index e4f5bc35f905..e4922d813d96 100644 --- a/WordPress/Classes/ViewRelated/Media/SiteMedia/Controllers/SiteMediaAddMediaMenuController.swift +++ b/WordPress/Classes/ViewRelated/Media/SiteMedia/Controllers/SiteMediaAddMediaMenuController.swift @@ -48,11 +48,9 @@ final class SiteMediaAddMediaMenuController: NSObject, PHPickerViewControllerDel return } - MediaHelper.advertiseImageOptimization() { [self] in - for result in results { - let info = MediaAnalyticsInfo(origin: .mediaLibrary(.deviceLibrary), selectionMethod: .fullScreenPicker) - coordinator.addMedia(from: result.itemProvider, to: blog, analyticsInfo: info) - } + for result in results { + let info = MediaAnalyticsInfo(origin: .mediaLibrary(.deviceLibrary), selectionMethod: .fullScreenPicker) + coordinator.addMedia(from: result.itemProvider, to: blog, analyticsInfo: info) } } @@ -71,9 +69,7 @@ final class SiteMediaAddMediaMenuController: NSObject, PHPickerViewControllerDel switch mediaType { case UTType.image.identifier: if let image = info[.originalImage] as? UIImage { - MediaHelper.advertiseImageOptimization() { - addAsset(from: image) - } + addAsset(from: image) } case UTType.movie.identifier: if let videoURL = info[.mediaURL] as? URL { diff --git a/WordPress/Classes/ViewRelated/Post/PostSettingsViewController+FeaturedImageUpload.swift b/WordPress/Classes/ViewRelated/Post/PostSettingsViewController+FeaturedImageUpload.swift index 2e993068bcff..984cbcb311d3 100644 --- a/WordPress/Classes/ViewRelated/Post/PostSettingsViewController+FeaturedImageUpload.swift +++ b/WordPress/Classes/ViewRelated/Post/PostSettingsViewController+FeaturedImageUpload.swift @@ -40,9 +40,7 @@ extension PostSettingsViewController: PHPickerViewControllerDelegate, ImagePicke public func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) { self.dismiss(animated: true) { if let result = results.first { - MediaHelper.advertiseImageOptimization() { [self] in - self.setFeaturedImage(with: result.itemProvider) - } + self.setFeaturedImage(with: result.itemProvider) } } } @@ -50,9 +48,7 @@ extension PostSettingsViewController: PHPickerViewControllerDelegate, ImagePicke func imagePicker(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) { self.dismiss(animated: true) { if let image = info[.originalImage] as? UIImage { - MediaHelper.advertiseImageOptimization() { [self] in - self.setFeaturedImage(with: image) - } + self.setFeaturedImage(with: image) } } } diff --git a/WordPress/Classes/ViewRelated/System/WPTabBarController+Swift.swift b/WordPress/Classes/ViewRelated/System/WPTabBarController+Swift.swift index 98d2a9e5e4eb..f3617c48ca4b 100644 --- a/WordPress/Classes/ViewRelated/System/WPTabBarController+Swift.swift +++ b/WordPress/Classes/ViewRelated/System/WPTabBarController+Swift.swift @@ -109,12 +109,23 @@ extension WPTabBarController { @objc func animateSelectedItem(_ item: UITabBarItem, for tabBar: UITabBar) { - guard let index = tabBar.items?.firstIndex(of: item), tabBar.subviews.count > index + 1 else { + // Order of subviews may not be guaranteed, so filter and sort them + let tabBarButtons = tabBar.subviews + .filter { $0 is UIControl } + .sorted { $0.frame.minX < $1.frame.minX } + + // The number of buttons should be the same as the number of tab bar items + guard tabBarButtons.count == tabBar.items?.count else { return } - let button = tabBar.subviews[(index + 1)] + // Get the button that corresponds to the selected tab bar item + guard let index = tabBar.items?.firstIndex(of: item), + let button = tabBarButtons[safe: index] else { + return + } + // Get the button's image view guard let imageView = button.subviews.lazy.compactMap({ $0 as? UIImageView }).first else { return } diff --git a/WordPress/Jetpack/Resources/AppStoreStrings.po b/WordPress/Jetpack/Resources/AppStoreStrings.po index b9a6a1c0ec64..f069ce80d2f8 100644 --- a/WordPress/Jetpack/Resources/AppStoreStrings.po +++ b/WordPress/Jetpack/Resources/AppStoreStrings.po @@ -81,17 +81,22 @@ msgctxt "app_store_keywords" msgid "social,notes,jetpack,writing,geotagging,media,blog,website,blogging,journal" msgstr "" -msgctxt "v24.0-whats-new" +msgctxt "v24.1-whats-new" msgid "" -"You can now get a WordPress plan with a free domain in the domain dashboard. We also made some improvements to the Site Domains screen so it’s even easier to manage your domains.\n" +"You’ll now see a notification when you’re working offline. Media uploads to image blocks will also pause when your internet connection cuts out, then resume when you reconnect.\n" +"As an added bonus, when you manually retry a failed media upload, the app will retry all other failed media uploads in your post. Now that’s efficient.\n" "\n" -"When you’re editing text blocks in the editor, your device’s keyboard will no longer disappear mid-edit. The editor will also scroll directly to a new block when you add it. Write away, friend.\n" +"When you select a custom gradient in the block editor, there’s now an indicator to show your chosen color.\n" "\n" -"Miss logging in with your security keys? Not anymore—we’ve re-enabled security keys for two-factor authentication during login. The only one getting into your account is you.\n" +"Scrolling through your images on the Site Media details screen will make them load ahead of time for a faster experience. Or maybe they were there all along.\n" "\n" -"We updated the colors of the login screen to match both WordPress and Jetpack. After all, teamwork makes the dream work.\n" +"We added support for higher-resolution thumbnails, GIF and video playback, documents, and other file previews. (homer-simpson-woohoo.gif)\n" "\n" -"Finally, we made assorted code fixes and tackled several rare (and not-so-rare) problems that were causing app crashes. These issues were mostly related to editing tags and categories, using duplicate tags, deleting posts, and editing deleted posts. All in a day’s work.\n" +"We switched up the publishing flow to give you clearer instructions. Users with the “Contributor” role will see the “Submit for Review” action instead of “Publish.” You can also trash draft posts and deleted posts without having to confirm.\n" +"\n" +"There’s now a “Share” action in the site context menu so you can share your site with others.\n" +"\n" +"Finally, because we live for the applause, we improved the in-app rating prompt. You’ll be asked to leave a review if you’re happy with the app, or given a feedback form if you feel the app needs work. Feedback is how we get better, so feel free to share yours!\n" msgstr "" #. translators: This is a promo message that will be attached on top of the first screenshot in the App Store. diff --git a/WordPress/Jetpack/Resources/release_notes.txt b/WordPress/Jetpack/Resources/release_notes.txt index c977a44b587f..82d5f86580ee 100644 --- a/WordPress/Jetpack/Resources/release_notes.txt +++ b/WordPress/Jetpack/Resources/release_notes.txt @@ -1,16 +1,14 @@ -* [*] Block Editor: Fix missing custom color indicator for custom gradients [https://github.com/WordPress/gutenberg/pull/57605] -* [**] Block Editor: Display a notice when a network connection is unavailable [https://github.com/WordPress/gutenberg/pull/56934] -* [**] Block Editor: Image block media uploads display a custom error message when there is no internet connection [https://github.com/wordpress-mobile/WordPress-iOS/pull/22282] -* [**] Image block media uploads display a custom error message when there is no internet connection [https://github.com/wordpress-mobile/WordPress-iOS/pull/22282] -* [**] Improve media previews on long-press: load higher-resolution thumbnails and increase the preview size, add support for GIFs and video playback, enable for documents and other files [#22274] -* [*] Add prefetching to Site Media details screen [#22292] -* [*] Allow trashing draft and scheduled posts with no confirmation [#22337] -* [*] Add "Share" action to the site context menu [#22298] -* [*] Update the post "Publish" context action for Contributors to "Submit for Review" instead of "Publish" [#22358] -* [**] Add a pre-publishing sheet to the "Publish" flow invoked from the post context menu as a replacement for a simple confirmation sheet [#22358] -* [**] Block Editor: Media uploads that failed due to lack of internet connectivity automatically retry once a connection is re-established [https://github.com/wordpress-mobile/WordPress-iOS/pull/22238] -* [**] Block Editor: Manually retrying a single failed media upload will retry all failed media uploads in a post [https://github.com/wordpress-mobile/WordPress-iOS/pull/22240] -* [*] [internal] Drop iOS 14 Support: Remove deprecated UIDocumentPickerViewController API [#22286] -* [***] [internal] Refactor WP.com sign in API requests [#22421] -* [*] Add In-App Feedback Prompt. [#22050] +You’ll now see a notification when you’re working offline. Media uploads to image blocks will also pause when your internet connection cuts out, then resume when you reconnect. +As an added bonus, when you manually retry a failed media upload, the app will retry all other failed media uploads in your post. Now that’s efficient. +When you select a custom gradient in the block editor, there’s now an indicator to show your chosen color. + +Scrolling through your images on the Site Media details screen will make them load ahead of time for a faster experience. Or maybe they were there all along. + +We added support for higher-resolution thumbnails, GIF and video playback, documents, and other file previews. (homer-simpson-woohoo.gif) + +We switched up the publishing flow to give you clearer instructions. Users with the “Contributor” role will see the “Submit for Review” action instead of “Publish.” You can also trash draft posts and deleted posts without having to confirm. + +There’s now a “Share” action in the site context menu so you can share your site with others. + +Finally, because we live for the applause, we improved the in-app rating prompt. You’ll be asked to leave a review if you’re happy with the app, or given a feedback form if you feel the app needs work. Feedback is how we get better, so feel free to share yours! diff --git a/WordPress/Resources/AppStoreStrings.po b/WordPress/Resources/AppStoreStrings.po index 1a7a59f29536..f1b12c846429 100644 --- a/WordPress/Resources/AppStoreStrings.po +++ b/WordPress/Resources/AppStoreStrings.po @@ -45,13 +45,22 @@ msgctxt "app_store_keywords" msgid "blogger,writing,blogging,web,maker,online,store,business,make,create,write,blogs" msgstr "" -msgctxt "v24.0-whats-new" +msgctxt "v24.1-whats-new" msgid "" -"When you’re editing text blocks in the editor, your device’s keyboard will no longer disappear mid-edit. The editor will also scroll directly to a new block when you add it. Write away, friend.\n" +"You’ll now see a notification when you’re working offline. Media uploads to image blocks will also pause when your internet connection cuts out, then resume when you reconnect.\n" +"As an added bonus, when you manually retry a failed media upload, the app will retry all other failed media uploads in your post. Now that’s efficient.\n" "\n" -"Miss logging in with your security keys? Not anymore—we’ve re-enabled security keys for two-factor authentication during login. The only one getting into your account is you.\n" +"When you select a custom gradient in the block editor, there’s now an indicator to show your chosen color.\n" "\n" -"Finally, we tackled several rare (and not-so-rare) problems that were causing app crashes. These issues were mostly related to editing tags and categories, using duplicate tags, deleting posts, and editing deleted posts. All in a day’s work.\n" +"Scrolling through your images on the Site Media details screen will make them load ahead of time for a faster experience. Or maybe they were there all along.\n" +"\n" +"We added support for higher-resolution thumbnails, GIF and video playback, documents, and other file previews. (homer-simpson-woohoo.gif)\n" +"\n" +"We switched up the publishing flow to give you clearer instructions. Users with the “Contributor” role will see the “Submit for Review” action instead of “Publish.” You can also trash draft posts and deleted posts without having to confirm.\n" +"\n" +"There’s now a “Share” action in the site context menu so you can share your site with others.\n" +"\n" +"Finally, because we live for the applause, we improved the in-app rating prompt. You’ll be asked to leave a review if you’re happy with the app, or given a feedback form if you feel the app needs work. Feedback is how we get better, so feel free to share yours!\n" msgstr "" #. translators: This is a standard chunk of text used to tell a user what's new with a release when nothing major has changed. diff --git a/WordPress/Resources/release_notes.txt b/WordPress/Resources/release_notes.txt index c977a44b587f..82d5f86580ee 100644 --- a/WordPress/Resources/release_notes.txt +++ b/WordPress/Resources/release_notes.txt @@ -1,16 +1,14 @@ -* [*] Block Editor: Fix missing custom color indicator for custom gradients [https://github.com/WordPress/gutenberg/pull/57605] -* [**] Block Editor: Display a notice when a network connection is unavailable [https://github.com/WordPress/gutenberg/pull/56934] -* [**] Block Editor: Image block media uploads display a custom error message when there is no internet connection [https://github.com/wordpress-mobile/WordPress-iOS/pull/22282] -* [**] Image block media uploads display a custom error message when there is no internet connection [https://github.com/wordpress-mobile/WordPress-iOS/pull/22282] -* [**] Improve media previews on long-press: load higher-resolution thumbnails and increase the preview size, add support for GIFs and video playback, enable for documents and other files [#22274] -* [*] Add prefetching to Site Media details screen [#22292] -* [*] Allow trashing draft and scheduled posts with no confirmation [#22337] -* [*] Add "Share" action to the site context menu [#22298] -* [*] Update the post "Publish" context action for Contributors to "Submit for Review" instead of "Publish" [#22358] -* [**] Add a pre-publishing sheet to the "Publish" flow invoked from the post context menu as a replacement for a simple confirmation sheet [#22358] -* [**] Block Editor: Media uploads that failed due to lack of internet connectivity automatically retry once a connection is re-established [https://github.com/wordpress-mobile/WordPress-iOS/pull/22238] -* [**] Block Editor: Manually retrying a single failed media upload will retry all failed media uploads in a post [https://github.com/wordpress-mobile/WordPress-iOS/pull/22240] -* [*] [internal] Drop iOS 14 Support: Remove deprecated UIDocumentPickerViewController API [#22286] -* [***] [internal] Refactor WP.com sign in API requests [#22421] -* [*] Add In-App Feedback Prompt. [#22050] +You’ll now see a notification when you’re working offline. Media uploads to image blocks will also pause when your internet connection cuts out, then resume when you reconnect. +As an added bonus, when you manually retry a failed media upload, the app will retry all other failed media uploads in your post. Now that’s efficient. +When you select a custom gradient in the block editor, there’s now an indicator to show your chosen color. + +Scrolling through your images on the Site Media details screen will make them load ahead of time for a faster experience. Or maybe they were there all along. + +We added support for higher-resolution thumbnails, GIF and video playback, documents, and other file previews. (homer-simpson-woohoo.gif) + +We switched up the publishing flow to give you clearer instructions. Users with the “Contributor” role will see the “Submit for Review” action instead of “Publish.” You can also trash draft posts and deleted posts without having to confirm. + +There’s now a “Share” action in the site context menu so you can share your site with others. + +Finally, because we live for the applause, we improved the in-app rating prompt. You’ll be asked to leave a review if you’re happy with the app, or given a feedback form if you feel the app needs work. Feedback is how we get better, so feel free to share yours! diff --git a/WordPress/UITests/Tests/AppSettingsTests.swift b/WordPress/UITests/Tests/AppSettingsTests.swift index 2589f0477553..0cd1726b9dd3 100644 --- a/WordPress/UITests/Tests/AppSettingsTests.swift +++ b/WordPress/UITests/Tests/AppSettingsTests.swift @@ -3,20 +3,10 @@ import XCTest final class AppSettingsTests: XCTestCase { - let testsRequiringAppDeletion = [ - "testImageOptimizationEnabledByDefault", - "testImageOptimizationIsTurnedOnEditor", - "testImageOptimizationIsTurnedOffEditor" - ] - @MainActor override func setUpWithError() throws { try super.setUpWithError() - - let removeBeforeLaunching = testsRequiringAppDeletion.contains { testName in - self.name.contains(testName) - } - setUpTestSuite(removeBeforeLaunching: removeBeforeLaunching) + setUpTestSuite() try LoginFlow .login(email: WPUITestCredentials.testWPcomUserEmail) @@ -33,28 +23,4 @@ final class AppSettingsTests: XCTestCase { .goToAppSettings() .verifyImageOptimizationSwitch(enabled: true) } - - func testImageOptimizationIsTurnedOnEditor() throws { - try TabNavComponent() - .goToBlockEditorScreen() - .addImage() - .chooseOptimizeImages(option: true) - .closeEditor() - try TabNavComponent() - .goToMeScreen() - .goToAppSettings() - .verifyImageOptimizationSwitch(enabled: true) - } - - func testImageOptimizationIsTurnedOffEditor() throws { - try TabNavComponent() - .goToBlockEditorScreen() - .addImage() - .chooseOptimizeImages(option: false) - .closeEditor() - try TabNavComponent() - .goToMeScreen() - .goToAppSettings() - .verifyImageOptimizationSwitch(enabled: false) - } } diff --git a/WordPress/UITestsFoundation/Screens/Editor/BlockEditorScreen.swift b/WordPress/UITestsFoundation/Screens/Editor/BlockEditorScreen.swift index 4def7eedb799..538bab40667b 100644 --- a/WordPress/UITestsFoundation/Screens/Editor/BlockEditorScreen.swift +++ b/WordPress/UITestsFoundation/Screens/Editor/BlockEditorScreen.swift @@ -96,14 +96,6 @@ public class BlockEditorScreen: ScreenObject { $0.staticTexts["You have unsaved changes."] } - private let leaveOnImageOptimizationButtonGetter: (XCUIApplication) -> XCUIElement = { - $0.buttons["Yes, leave on"] - } - - private let turnOffImageOptimizationButtonGetter: (XCUIApplication) -> XCUIElement = { - $0.buttons["No, turn off"] - } - var addBlockButton: XCUIElement { addBlockButtonGetter(app) } var chooseFromDeviceButton: XCUIElement { chooseFromDeviceButtonGetter(app) } var closeButton: XCUIElement { closeButtonGetter(app) } @@ -127,8 +119,6 @@ public class BlockEditorScreen: ScreenObject { var switchToHTMLModeButton: XCUIElement { switchToHTMLModeButtonGetter(app) } var undoButton: XCUIElement { undoButtonGetter(app) } var unsavedChangesLabel: XCUIElement { unsavedChangesLabelGetter(app) } - var leaveOnImageOptimizationButton: XCUIElement { leaveOnImageOptimizationButtonGetter(app) } - var turnOffImageOptimizationButton: XCUIElement { turnOffImageOptimizationButtonGetter(app) } public init(app: XCUIApplication = XCUIApplication()) throws { // The block editor has _many_ elements but most are loaded on-demand. To verify the screen @@ -197,32 +187,10 @@ public class BlockEditorScreen: ScreenObject { public func addImageGallery() throws -> BlockEditorScreen { addBlock("Gallery block") try addMultipleImages(numberOfImages: 3) - try dismissImageOptimizationPopupIfNeeded() - - return self - } - - /** - Chooses the option of Optimize Images popup. - */ - @discardableResult - public func chooseOptimizeImages(option: Bool) throws -> BlockEditorScreen { - if option { - leaveOnImageOptimizationButton.tap() - } - else { - turnOffImageOptimizationButton.tap() - } return self } - public func dismissImageOptimizationPopupIfNeeded() throws { - if leaveOnImageOptimizationButton.waitForIsHittable() { - try chooseOptimizeImages(option: true) - } - } - public func addVideoFromUrl(urlPath: String) -> Self { addMediaBlockFromUrl( blockType: "Video block", @@ -462,7 +430,6 @@ public class BlockEditorScreen: ScreenObject { private func addMultipleImages(numberOfImages: Int) throws { try chooseFromDevice() .selectMultipleImages(numberOfImages) - try dismissImageOptimizationPopupIfNeeded() } private func chooseFromDevice() throws -> PHPickerScreen { diff --git a/WordPress/UITestsFoundation/Screens/MySiteScreen.swift b/WordPress/UITestsFoundation/Screens/MySiteScreen.swift index f64833667779..218f66297904 100644 --- a/WordPress/UITestsFoundation/Screens/MySiteScreen.swift +++ b/WordPress/UITestsFoundation/Screens/MySiteScreen.swift @@ -96,13 +96,10 @@ public class MySiteScreen: ScreenObject { $0.buttons["site-url-button"] } - private let siteActionButtonGetter: (XCUIApplication) -> XCUIElement = { - $0.buttons["site-action-button"] - } - private let switchSiteButtonGetter: (XCUIApplication) -> XCUIElement = { - $0.buttons["Switch site"] + $0.buttons["switch-site-button"] } + var activityLogCard: XCUIElement { activityLogCardGetter(app) } var activityLogCardHeaderButton: XCUIElement { activityLogCardHeaderButtonGetter(app) } var blogDetailsRemoveSiteButton: XCUIElement { blogDetailsRemoveSiteButtonGetter(app) } @@ -124,7 +121,6 @@ public class MySiteScreen: ScreenObject { var segmentedControlMenuButton: XCUIElement { segmentedControlMenuButtonGetter(app) } var siteTitleButton: XCUIElement { siteTitleButtonGetter(app) } var siteUrlButton: XCUIElement { siteUrlButtonGetter(app) } - var siteActionButton: XCUIElement { siteActionButtonGetter(app) } var switchSiteButton: XCUIElement { switchSiteButtonGetter(app) } // Timeout duration to overwrite value defined in XCUITestHelpers @@ -133,7 +129,7 @@ public class MySiteScreen: ScreenObject { public init(app: XCUIApplication = XCUIApplication()) throws { try super.init( expectedElementGetters: [ - siteActionButtonGetter, + switchSiteButtonGetter, createButtonGetter ], app: app @@ -141,7 +137,6 @@ public class MySiteScreen: ScreenObject { } public func showSiteSwitcher() throws -> MySitesScreen { - siteActionButton.tap() switchSiteButton.tap() return try MySitesScreen() } diff --git a/WordPress/WordPressTest/MediaSettingsTests.swift b/WordPress/WordPressTest/MediaSettingsTests.swift index b2e38489bd25..d1063bac0380 100644 --- a/WordPress/WordPressTest/MediaSettingsTests.swift +++ b/WordPress/WordPressTest/MediaSettingsTests.swift @@ -23,12 +23,6 @@ class MediaSettingsTests: XCTestCase { expect(imageQuality).to(equal(.medium)) } - func testDefaultAdvertiseImageOptimization() { - let settings = MediaSettings(database: EphemeralKeyValueDatabase()) - let advertiseImageOptimization = settings.advertiseImageOptimization - expect(advertiseImageOptimization).to(beTrue()) - } - // MARK: - Max Image Size values func testMaxImageSizeMigratesCGSizeToInt() { let dimension = Int(1200) @@ -74,11 +68,4 @@ class MediaSettingsTests: XCTestCase { settings.imageOptimizationEnabled = false expect(settings.imageQualityForUpload).to(equal(.high)) } - - func testAdvertiseImageOptimizationValueBasedOnOptimization() { - let settings = MediaSettings(database: EphemeralKeyValueDatabase()) - expect(settings.advertiseImageOptimization).to(beTrue()) - settings.imageOptimizationEnabled = false - expect(settings.advertiseImageOptimization).to(beFalse()) - } }