diff --git a/Sources/Keystone/WordPress.h b/Sources/Keystone/WordPress.h index 6649cba7c660..a872eef38340 100644 --- a/Sources/Keystone/WordPress.h +++ b/Sources/Keystone/WordPress.h @@ -26,9 +26,7 @@ FOUNDATION_EXPORT const unsigned char WordPressVersionString[]; #import -#import #import -#import #import #import diff --git a/Sources/WordPressData/Objective-C/AbstractPost.m b/Sources/WordPressData/Objective-C/AbstractPost.m index 5a4ad2b632e9..7f34f36528c6 100644 --- a/Sources/WordPressData/Objective-C/AbstractPost.m +++ b/Sources/WordPressData/Objective-C/AbstractPost.m @@ -320,11 +320,6 @@ - (BOOL)isPrivateAtWPCom return self.blog.isPrivateAtWPCom; } -- (BOOL)isMultiAuthorBlog -{ - return self.blog.isMultiAuthor; -} - - (BOOL)isUploading { return self.remoteStatus == AbstractPostRemoteStatusPushing; diff --git a/Sources/WordPressData/Objective-C/include/AbstractPost.h b/Sources/WordPressData/Objective-C/include/AbstractPost.h index b31bf4fd4002..304aa8f5e8bd 100644 --- a/Sources/WordPressData/Objective-C/include/AbstractPost.h +++ b/Sources/WordPressData/Objective-C/include/AbstractPost.h @@ -86,7 +86,6 @@ typedef NS_ENUM(NSUInteger, AbstractPostRemoteStatus) { - (NSString *)authorNameForDisplay; - (NSString *)blavatarForDisplay; - (NSString *)dateStringForDisplay; -- (BOOL)isMultiAuthorBlog; - (BOOL)isPrivateAtWPCom; diff --git a/Sources/WordPressData/Swift/AbstractPost.swift b/Sources/WordPressData/Swift/AbstractPost.swift index 0cd6c0c8bb90..cf593b386c2c 100644 --- a/Sources/WordPressData/Swift/AbstractPost.swift +++ b/Sources/WordPressData/Swift/AbstractPost.swift @@ -101,13 +101,6 @@ public extension AbstractPost { } } - // MARK: - Misc - - /// A title describing the status. Ie.: "Public" or "Private" or "Password protected" - @objc var titleForVisibility: String { - PostVisibility(post: self).localizedTitle - } - /// Represent the supported properties used to sort posts. /// enum SortField { diff --git a/Sources/WordPressData/Swift/Post.swift b/Sources/WordPressData/Swift/Post.swift index 8f11c9d1b75a..70c2f20e62b9 100644 --- a/Sources/WordPressData/Swift/Post.swift +++ b/Sources/WordPressData/Swift/Post.swift @@ -65,21 +65,6 @@ public class Post: AbstractPost { // MARK: - Categories - /// Returns categories as a comma-separated list - /// - @objc public func categoriesText() -> String { - - guard let allStrings = categories?.map({ return $0.categoryName as String }) else { - return "" - } - - let orderedStrings = allStrings.sorted { (categoryName1, categoryName2) -> Bool in - return categoryName1.localizedCaseInsensitiveCompare(categoryName2) == .orderedAscending - } - - return orderedStrings.joined(separator: ", ") - } - /// Set the categories for a post /// /// - Parameter categoryNames: a `NSArray` with the names of the categories for this post. If @@ -119,7 +104,7 @@ public class Post: AbstractPost { let isKeyringEntryDisabled = disabledPublicizeConnections?[keyringID]?[Constants.publicizeValueKey] == Constants.publicizeDisabledValue // try to check in case there's an entry for the PublicizeConnection that's keyed by the connectionID. - guard let connections = blog.connections as? Set, + guard let connections = blog.connections, let connection = connections.first(where: { $0.keyringConnectionID == keyringID }), let existingValue = disabledPublicizeConnections?[connection.connectionID]?[Constants.publicizeValueKey] else { // fall back to keyringID if there is no such entry with the connectionID. @@ -130,10 +115,10 @@ public class Post: AbstractPost { return isConnectionEntryDisabled || isKeyringEntryDisabled } - @objc public func enablePublicizeConnectionWithKeyringID(_ keyringID: NSNumber) { + public func enablePublicizeConnectionWithKeyringID(_ keyringID: NSNumber) { // if there's another entry keyed by connectionID references to the same connection, // we need to make sure that the values are kept in sync. - if let connections = blog.connections as? Set, + if let connections = blog.connections, let connection = connections.first(where: { $0.keyringConnectionID == keyringID }), let _ = disabledPublicizeConnections?[connection.connectionID] { enablePublicizeConnection(keyedBy: connection.connectionID) @@ -142,10 +127,10 @@ public class Post: AbstractPost { enablePublicizeConnection(keyedBy: keyringID) } - @objc public func disablePublicizeConnectionWithKeyringID(_ keyringID: NSNumber) { + public func disablePublicizeConnectionWithKeyringID(_ keyringID: NSNumber) { // if there's another entry keyed by connectionID references to the same connection, // we need to make sure that the values are kept in sync. - if let connections = blog.connections as? Set, + if let connections = blog.connections, let connectionID = connections.first(where: { $0.keyringConnectionID == keyringID })?.connectionID, let _ = disabledPublicizeConnections?[connectionID] { disablePublicizeConnection(keyedBy: connectionID) diff --git a/Sources/WordPressData/Swift/PostHelper+JetpackSocial.swift b/Sources/WordPressData/Swift/PostHelper+JetpackSocial.swift index 28001063c11a..9b7ee14d11cd 100644 --- a/Sources/WordPressData/Swift/PostHelper+JetpackSocial.swift +++ b/Sources/WordPressData/Swift/PostHelper+JetpackSocial.swift @@ -43,7 +43,7 @@ extension PostHelper { // the connectionID, and return its keyringID. let entryConnectionID = Int(key.removingPrefix(SkipPrefix.connection.rawValue)) - guard let connections = post.blog.connections as? Set, + guard let connections = post.blog.connections, let connectionID = entryConnectionID, let connection = connections.first(where: { $0.connectionID.intValue == connectionID }) else { /// Otherwise, fall back to the connectionID extracted from the metadata key. @@ -94,7 +94,7 @@ extension PostHelper { // Try to add a key with the new format ONLY if the metadata hasn't been synced to the remote. let metadataKeyValue: String = { guard entry[Keys.publicizeIdKey] == nil, - let connections = post.blog.connections as? Set, + let connections = post.blog.connections, let connection = connections.first(where: { $0.keyringConnectionID == keyringID }) else { // Fall back to the old keyring format. return "\(SkipPrefix.keyring.rawValue)\(keyringID)" diff --git a/Tests/KeystoneTests/Tests/Features/Posts/PublishSettingsControllerTests.swift b/Tests/KeystoneTests/Tests/Features/Posts/PublishSettingsControllerTests.swift deleted file mode 100644 index 5986efea72ed..000000000000 --- a/Tests/KeystoneTests/Tests/Features/Posts/PublishSettingsControllerTests.swift +++ /dev/null @@ -1,86 +0,0 @@ -import XCTest -@testable import WordPress -@testable import WordPressData - -class PublishSettingsViewControllerTests: CoreDataTestCase { - - func testViewModelDateScheduled() { - let testDate = Date().addingTimeInterval(5000) - - let post = PostBuilder(mainContext).with(dateCreated: testDate).drafted().withRemote().build() - - var viewModel = PublishSettingsViewModel(post: post) - XCTAssertEqual(viewModel.date, testDate, "Date should exist in view model") - - if case PublishSettingsViewModel.State.scheduled(_) = viewModel.state { - // Success - } else { - XCTFail("View model should be scheduled") - } - - viewModel.setDate(testDate) - - if case PublishSettingsViewModel.State.scheduled(_) = viewModel.state { - // Success - } else { - XCTFail("View model should be scheduled instead of \(viewModel.state)") - } - } - - func testViewModelDateImmediately() { - let testDate = Date() - - let post = PostBuilder(mainContext).drafted().withRemote().build() - - var viewModel = PublishSettingsViewModel(post: post) - XCTAssertNil(viewModel.date, "Date should not exist in view model") - - if case PublishSettingsViewModel.State.immediately = viewModel.state { - // Success - } else { - XCTFail("View model should be immediately instead of \(viewModel.state)") - } - - viewModel.setDate(testDate) - - if case PublishSettingsViewModel.State.published(_) = viewModel.state { - // Success - } else { - XCTFail("View model should be published instead of \(viewModel.state)") - } - } - - func testViewModelDatePublished() { - let testDate = Date() - - let post = PostBuilder(mainContext).with(dateCreated: testDate).published().withRemote().build() - - var viewModel = PublishSettingsViewModel(post: post) - XCTAssertEqual(viewModel.date, testDate, "Date should exist in view model") - - if case PublishSettingsViewModel.State.published(_) = viewModel.state { - // Success - } else { - XCTFail("View model should be published instead of \(viewModel.state)") - } - - viewModel.setDate(testDate) - - if case PublishSettingsViewModel.State.published(_) = viewModel.state { - // Success - } else { - XCTFail("View model should be published instead of \(viewModel.state)") - } - } -} - -extension PublishSettingsViewControllerTests { - // MARK: - Private Helpers - fileprivate func newSettings() -> BlogSettings { - let context = contextManager.mainContext - let name = BlogSettings.classNameWithoutNamespaces() - let entity = NSEntityDescription.insertNewObject(forEntityName: name, into: context) - - return entity as! BlogSettings - } -} diff --git a/Tests/KeystoneTests/Tests/Models/PostTests.swift b/Tests/KeystoneTests/Tests/Models/PostTests.swift index 317467ef6633..3b61bc0d6a7e 100644 --- a/Tests/KeystoneTests/Tests/Models/PostTests.swift +++ b/Tests/KeystoneTests/Tests/Models/PostTests.swift @@ -25,24 +25,6 @@ class PostTests: CoreDataTestCase { return category } - func testThatNoCategoriesReturnEmptyStringWhenCallingCategoriesText() { - let post = newTestPost() - let categoriesText = post.categoriesText() - - XCTAssertEqual(categoriesText, "") - } - - func testThatSomeCategoriesReturnAListWhenCallingCategoriesText() { - - let post = newTestPost() - - post.categories = [newTestPostCategory("1"), newTestPostCategory("2"), newTestPostCategory("3")] - - let categoriesText = post.categoriesText() - - XCTAssertEqual(categoriesText, "1, 2, 3") - } - func testSetCategoriesFromNamesWithTwoCategories() { let blog = newTestBlog() let post = newTestPost() diff --git a/Tests/KeystoneTests/Tests/Services/SharingServiceTests.swift b/Tests/KeystoneTests/Tests/Services/SharingServiceTests.swift index 67b842db8bd0..6ca7bfa6be56 100644 --- a/Tests/KeystoneTests/Tests/Services/SharingServiceTests.swift +++ b/Tests/KeystoneTests/Tests/Services/SharingServiceTests.swift @@ -70,7 +70,7 @@ class SharingServiceTests: CoreDataTestCase { } // Then - let connections = try XCTUnwrap(blog.connections as? Set) + let connections = try XCTUnwrap(blog.connections) // the one with ID `1002` should be skipped since it's an unshared private connection from another user. XCTAssertEqual(connections.count, 2) diff --git a/WordPress/Classes/System/WordPress-Bridging-Header.h b/WordPress/Classes/System/WordPress-Bridging-Header.h index 4108eb25fe20..d76db2d76094 100644 --- a/WordPress/Classes/System/WordPress-Bridging-Header.h +++ b/WordPress/Classes/System/WordPress-Bridging-Header.h @@ -18,9 +18,7 @@ #import "NSObject+Helpers.h" -#import "PageSettingsViewController.h" #import "PostCategoryService.h" -#import "PostSettingsViewController.h" #import "PostTagService.h" #import "ReaderPostService.h" diff --git a/WordPress/Classes/Utility/BuildInformation/FeatureFlag.swift b/WordPress/Classes/Utility/BuildInformation/FeatureFlag.swift index fc95fdf9bb50..d6d2501c6675 100644 --- a/WordPress/Classes/Utility/BuildInformation/FeatureFlag.swift +++ b/WordPress/Classes/Utility/BuildInformation/FeatureFlag.swift @@ -26,7 +26,6 @@ public enum FeatureFlag: Int, CaseIterable { case pluginManagementOverhaul case nativeJetpackConnection case newsletterSubscribers - case postSettingsV2 /// Returns a boolean indicating if the feature is enabled. /// @@ -83,8 +82,6 @@ public enum FeatureFlag: Int, CaseIterable { return BuildConfiguration.current == .debug case .newsletterSubscribers: return true - case .postSettingsV2: - return false } } @@ -128,7 +125,6 @@ extension FeatureFlag { case .readerGutenbergCommentComposer: "Gutenberg Comment Composer" case .nativeJetpackConnection: "Native Jetpack Connection" case .newsletterSubscribers: "Newsletter Subscribers" - case .postSettingsV2: "Post Settings V2" } } } diff --git a/WordPress/Classes/ViewRelated/Blog/Sharing/WPStyleGuide+Sharing.swift b/WordPress/Classes/ViewRelated/Blog/Sharing/WPStyleGuide+Sharing.swift index bed0a181220b..145ff1700ced 100644 --- a/WordPress/Classes/ViewRelated/Blog/Sharing/WPStyleGuide+Sharing.swift +++ b/WordPress/Classes/ViewRelated/Blog/Sharing/WPStyleGuide+Sharing.swift @@ -43,7 +43,7 @@ extension WPStyleGuide { /// /// - Returns: A template UIImage that can be tinted by a UIImageView's tintColor property. /// - @objc public class func iconForService(_ service: NSString) -> UIImage { + public class func iconForService(_ service: NSString) -> UIImage { let name = service.lowercased.replacingOccurrences(of: "_", with: "-") var iconName: String @@ -68,7 +68,7 @@ extension WPStyleGuide { return image!.withRenderingMode(.alwaysTemplate) } - @objc public class func socialIcon(for service: NSString) -> UIImage { + public class func socialIcon(for service: NSString) -> UIImage { UIImage(named: "icon-\(service)") ?? iconForService(service) } } diff --git a/WordPress/Classes/ViewRelated/Gutenberg/GutenbergViewController.swift b/WordPress/Classes/ViewRelated/Gutenberg/GutenbergViewController.swift index 8462533307dd..7f31dd581d12 100644 --- a/WordPress/Classes/ViewRelated/Gutenberg/GutenbergViewController.swift +++ b/WordPress/Classes/ViewRelated/Gutenberg/GutenbergViewController.swift @@ -11,7 +11,7 @@ import AutomatticTracks import Combine import ImagePlayground -class GutenbergViewController: UIViewController, PostEditor, FeaturedImageDelegate, PublishingEditor { +class GutenbergViewController: UIViewController, PostEditor, PublishingEditor { let errorDomain: String = "GutenbergViewController.errorDomain" enum RequestHTMLReason { diff --git a/WordPress/Classes/ViewRelated/Pages/PageSettingsViewController.h b/WordPress/Classes/ViewRelated/Pages/PageSettingsViewController.h deleted file mode 100644 index c78d0f33603e..000000000000 --- a/WordPress/Classes/ViewRelated/Pages/PageSettingsViewController.h +++ /dev/null @@ -1,5 +0,0 @@ -#import "PostSettingsViewController.h" - -@interface PageSettingsViewController : PostSettingsViewController - -@end diff --git a/WordPress/Classes/ViewRelated/Pages/PageSettingsViewController.m b/WordPress/Classes/ViewRelated/Pages/PageSettingsViewController.m deleted file mode 100644 index 6ed931aa4b93..000000000000 --- a/WordPress/Classes/ViewRelated/Pages/PageSettingsViewController.m +++ /dev/null @@ -1,34 +0,0 @@ -#import "PageSettingsViewController.h" -#import "PostSettingsViewController_Internal.h" -#ifdef KEYSTONE -#import "Keystone-Swift.h" -#else -#import "WordPress-Swift.h" -#endif - -@interface PageSettingsViewController () - -@end - -@implementation PageSettingsViewController - -- (void)configureSections -{ - self.sections = @[ - @(PostSettingsSectionMeta), - @(PostSettingsSectionFeaturedImage), - @(PostSettingsSectionMoreOptions), - @(PostSettingsSectionPageAttributes) - ]; -} - -- (Page *)page -{ - if ([self.apost isKindOfClass:[Page class]]) { - return (Page *)self.apost; - } - - return nil; -} - -@end diff --git a/WordPress/Classes/ViewRelated/Post/PostEditor+MoreOptions.swift b/WordPress/Classes/ViewRelated/Post/PostEditor+MoreOptions.swift index 5fb39ab8f236..05b296bad156 100644 --- a/WordPress/Classes/ViewRelated/Post/PostEditor+MoreOptions.swift +++ b/WordPress/Classes/ViewRelated/Post/PostEditor+MoreOptions.swift @@ -8,9 +8,6 @@ extension PostEditor { @MainActor func displayPostSettings() { - guard FeatureFlag.postSettingsV2.enabled else { - return showDeprecatedPostSettings() - } // Use the new SwiftUI-based Post Settings let originalFeaturedImageID = post.featuredImage?.mediaID let viewModel = PostSettingsViewModel(post: post) @@ -27,25 +24,11 @@ extension PostEditor { self?.navigationController?.dismiss(animated: true) } - let postSettingsVC = NewPostSettingsViewController(viewModel: viewModel) + let postSettingsVC = PostSettingsViewController(viewModel: viewModel) let navigation = UINavigationController(rootViewController: postSettingsVC) self.navigationController?.present(navigation, animated: true) } - private func showDeprecatedPostSettings() { - let viewController = PostSettingsViewController.make(for: post) - viewController.featuredImageDelegate = self as? FeaturedImageDelegate - let doneButton = UIBarButtonItem(systemItem: .done, primaryAction: .init(handler: { [weak self] _ in - self?.editorContentWasUpdated() - self?.navigationController?.dismiss(animated: true) - })) - doneButton.accessibilityIdentifier = "close" - viewController.navigationItem.rightBarButtonItem = doneButton - - let navigation = UINavigationController(rootViewController: viewController) - self.navigationController?.present(navigation, animated: true) - } - private func savePostBeforePreview(completion: @escaping ((String?, Error?) -> Void)) { guard !post.changes.isEmpty || post.original().isNewDraft else { completion(nil, nil) diff --git a/WordPress/Classes/ViewRelated/Post/PostSettings/PostSettingsView.swift b/WordPress/Classes/ViewRelated/Post/PostSettings/PostSettingsView.swift index 2d28e01d80c3..5f173bf7283f 100644 --- a/WordPress/Classes/ViewRelated/Post/PostSettings/PostSettingsView.swift +++ b/WordPress/Classes/ViewRelated/Post/PostSettings/PostSettingsView.swift @@ -7,7 +7,7 @@ import WordPressShared import WordPressUI import SwiftUI -final class NewPostSettingsViewController: UIHostingController { +final class PostSettingsViewController: UIHostingController { private let viewModel: PostSettingsViewModel init(viewModel: PostSettingsViewModel) { @@ -33,6 +33,13 @@ final class NewPostSettingsViewController: UIHostingController { @preconcurrency required dynamic init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } + + static func showStandaloneEditor(for post: AbstractPost, from presentingVC: UIViewController) { + let viewModel = PostSettingsViewModel(post: post, isStandalone: true) + let postSettingsVC = PostSettingsViewController(viewModel: viewModel) + let navigation = UINavigationController(rootViewController: postSettingsVC) + presentingVC.present(navigation, animated: true) + } } @MainActor diff --git a/WordPress/Classes/ViewRelated/Post/PostSettingsViewController+JetpackSocial.swift b/WordPress/Classes/ViewRelated/Post/PostSettingsViewController+JetpackSocial.swift deleted file mode 100644 index ca158908c2a7..000000000000 --- a/WordPress/Classes/ViewRelated/Post/PostSettingsViewController+JetpackSocial.swift +++ /dev/null @@ -1,186 +0,0 @@ -import SwiftUI -import AutomatticTracks -import WordPressData -import WordPressShared - -extension PostSettingsViewController { - - // MARK: - No connection view - - @objc public func showNoConnection() -> Bool { - let isJetpackSocialEnabled = RemoteFeatureFlag.jetpackSocialImprovements.enabled() - let isNoConnectionViewHidden = UserPersistentStoreFactory.instance().bool(forKey: hideNoConnectionViewKey()) - let blogSupportsPublicize = apost.blog.supportsPublicize() - let blogHasNoConnections = publicizeConnections.count == 0 && unsupportedConnections.count == 0 - let blogHasServices = availableServices().count > 0 - - return isJetpackSocialEnabled - && !isNoConnectionViewHidden - && blogSupportsPublicize - && blogHasNoConnections - && blogHasServices - && !isPostPrivate - } - - @objc public func createNoConnectionView() -> UIView { - WPAnalytics.track(.jetpackSocialNoConnectionCardDisplayed, - properties: ["source": Constants.trackingSource]) - let services = availableServices() - let viewModel = JetpackSocialNoConnectionViewModel(services: services, - onConnectTap: onConnectTap(), - onNotNowTap: onNotNowTap()) - let viewController = JetpackSocialNoConnectionView.createHostController(with: viewModel) - - // Returning just the view means the view controller will deallocate but we don't need a - // reference to it. The view itself holds onto the view model. - return viewController.view - } - - // MARK: - Remaining shares view - - @objc public func showRemainingShares() -> Bool { - let isJetpackSocialEnabled = RemoteFeatureFlag.jetpackSocialImprovements.enabled() - let blogSupportsPublicize = apost.blog.supportsPublicize() - let blogHasConnections = publicizeConnections.count > 0 - let blogHasSharingLimit = apost.blog.sharingLimit != nil - - return isJetpackSocialEnabled - && blogSupportsPublicize - && blogHasConnections - && blogHasSharingLimit - && !isPostPrivate - } - - @objc public func createRemainingSharesView() -> UIView { - guard let sharingLimit = apost.blog.sharingLimit else { - // This scenario *shouldn't* happen since we check that the publicize info is not nil before - // showing this view - assertionFailure("No sharing limit on the blog") - let error = JetpackSocialError.missingSharingLimit - CrashLogging.main.logError(error, userInfo: ["source": "post_settings"]) - return UIView() - } - WPAnalytics.track(.jetpackSocialShareLimitDisplayed, - properties: ["source": Constants.trackingSource]) - - let shouldDisplayWarning = publicizeConnections.count > sharingLimit.remaining - let viewModel = JetpackSocialRemainingSharesViewModel(remaining: sharingLimit.remaining, - displayWarning: shouldDisplayWarning, - onSubscribeTap: onSubscribeTap()) - let hostController = UIHostingController(rootView: JetpackSocialSettingsRemainingSharesView(viewModel: viewModel)) - hostController.view.translatesAutoresizingMaskIntoConstraints = false - hostController.view.backgroundColor = .secondarySystemGroupedBackground - return hostController.view - } - - // MARK: - Social share cells - - @objc public func userCanEditSharing() -> Bool { - guard let post = self.apost as? Post else { - return false - } - guard RemoteFeatureFlag.jetpackSocialImprovements.enabled() else { - return post.canEditPublicizeSettings() - } - - return post.canEditPublicizeSettings() && remainingSocialShares() > 0 - } - - @objc public func remainingSocialShares() -> Int { - self.apost.blog.sharingLimit?.remaining ?? .max - } - -} - -// MARK: - Private methods - -private extension PostSettingsViewController { - - var isPostPrivate: Bool { - apost.status == .publishPrivate - } - - func hideNoConnectionViewKey() -> String { - guard let dotComID = apost.blog.dotComID?.stringValue else { - return Constants.hideNoConnectionViewKey - } - - return "\(dotComID)-\(Constants.hideNoConnectionViewKey)" - } - - func onConnectTap() -> () -> Void { - return { [weak self] in - WPAnalytics.track(.jetpackSocialNoConnectionCTATapped, - properties: ["source": Constants.trackingSource]) - guard let blog = self?.apost.blog, - let controller = SharingViewController(blog: blog, delegate: nil) else { - return - } - self?.navigationController?.pushViewController(controller, animated: true) - } - } - - func onNotNowTap() -> () -> Void { - return { [weak self] in - WPAnalytics.track(.jetpackSocialNoConnectionCardDismissed, - properties: ["source": Constants.trackingSource]) - guard let key = self?.hideNoConnectionViewKey() else { - return - } - UserPersistentStoreFactory.instance().set(true, forKey: key) - self?.tableView.reloadData() - } - } - - func onSubscribeTap() -> () -> Void { - return { [weak self] in - WPAnalytics.track(.jetpackSocialUpgradeLinkTapped, - properties: ["source": Constants.trackingSource]) - guard let blog = self?.apost.blog, - let hostname = blog.hostname, - let url = URL(string: "https://wordpress.com/checkout/\(hostname)/jetpack_social_basic_yearly") else { - return - } - let webViewController = WebViewControllerFactory.controller(url: url, - blog: blog, - source: "post_settings_remaining_shares_subscribe_now") { - self?.checkoutDismissed() - } - let navigationController = UINavigationController(rootViewController: webViewController) - self?.present(navigationController, animated: true) - } - } - - func checkoutDismissed() { - let coreDataStack = ContextManager.shared - let service = BlogService(coreDataStack: coreDataStack) - service.syncBlog(apost.blog) { [weak self] in - let sharingLimit: PublicizeInfo.SharingLimit? = coreDataStack.performQuery { context in - guard let dotComID = self?.apost.blog.dotComID, - let blog = Blog.lookup(withID: dotComID, in: context) else { - return nil - } - return blog.sharingLimit - } - if sharingLimit == nil { - self?.reloadData() - } - } failure: { error in - DDLogError("Failed to sync blog after dismissing checkout webview due to error: \(error)") - } - } - - func availableServices() -> [PublicizeService] { - let context = apost.managedObjectContext ?? ContextManager.shared.mainContext - let services = try? PublicizeService.allSupportedServices(in: context) - return services ?? [] - } - - // MARK: - Constants - - struct Constants { - static let hideNoConnectionViewKey = "post-settings-social-no-connection-view-hidden" - static let trackingSource = "post_settings" - } - -} diff --git a/WordPress/Classes/ViewRelated/Post/PostSettingsViewController+Swift.swift b/WordPress/Classes/ViewRelated/Post/PostSettingsViewController+Swift.swift deleted file mode 100644 index 7334274480d3..000000000000 --- a/WordPress/Classes/ViewRelated/Post/PostSettingsViewController+Swift.swift +++ /dev/null @@ -1,341 +0,0 @@ -import UIKit -import CoreData -import Combine -import WordPressData -import WordPressKit -import WordPressShared -import SwiftUI - -extension PostSettingsViewController { - static func make(for post: AbstractPost) -> PostSettingsViewController { - switch post { - case let post as Post: - return PostSettingsViewController(post: post) - case let page as Page: - return PageSettingsViewController(post: page) - default: - fatalError("Unsupported entity: \(post)") - } - } - - static func showStandaloneEditor(for post: AbstractPost, from presentingVC: UIViewController) { - if FeatureFlag.postSettingsV2.enabled { - let viewModel = PostSettingsViewModel(post: post, isStandalone: true) - let postSettingsVC = NewPostSettingsViewController(viewModel: viewModel) - let navigation = UINavigationController(rootViewController: postSettingsVC) - presentingVC.present(navigation, animated: true) - } else { - let revision = post.createRevision() - let viewController = PostSettingsViewController.make(for: revision) - viewController.isStandalone = true - let navigation = UINavigationController(rootViewController: viewController) - presentingVC.present(navigation, animated: true) - } - } - - @objc public var isDraftOrPending: Bool { - apost.original().isStatus(in: [.draft, .pending]) - } - - @objc public func onViewDidLoad() { - if isStandalone { - setupStandaloneEditor() - } - if let postID = apost.postID, postID.intValue > 0 { - tableView.tableFooterView = EntityMetadataTableFooterView.make(id: postID) - } - } - - private func setupStandaloneEditor() { - wpAssert(navigationController?.presentationController != nil) - navigationController?.presentationController?.delegate = self - - refreshNavigationBarButtons() - navigationItem.rightBarButtonItem?.isEnabled = false - - var cancellables: [AnyCancellable] = [] - - let originalPostID = (apost.original ?? apost).objectID - - NotificationCenter.default - .publisher(for: NSManagedObjectContext.didChangeObjectsNotification, object: apost.managedObjectContext) - .sink { [weak self] notification in - self?.didChangeObjects(notification, originalPostID: originalPostID) - }.store(in: &cancellables) - - NotificationCenter.default - .publisher(for: UIApplication.willTerminateNotification) - .sink { [weak self] _ in - self?.deleteRevision() - }.store(in: &cancellables) - - apost.objectWillChange.sink { [weak self] in - self?.didUpdateSettings() - }.store(in: &cancellables) - - objc_setAssociatedObject(self, &PostSettingsViewController.cancellablesKey, cancellables, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) - } - - private func didUpdateSettings() { - navigationItem.rightBarButtonItem?.isEnabled = !changes.isEmpty - } - - private func refreshNavigationBarButtons() { - navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(buttonCancelTapped)) - - let buttonSave = UIBarButtonItem(barButtonSystemItem: isStandalone ? .save : .done, target: self, action: #selector(buttonSaveTapped)) - buttonSave.accessibilityLabel = "save" - navigationItem.rightBarButtonItem = buttonSave - } - - @objc private func buttonCancelTapped() { - wpAssert(self.isStandalone, "should only be shown for a standalone editor") - deleteRevision() - presentingViewController?.dismiss(animated: true) - } - - @objc private func buttonSaveTapped() { - navigationItem.rightBarButtonItem = .activityIndicator - setEnabled(false) - - Task { @MainActor in - do { - let coordinator = PostCoordinator.shared - if coordinator.isSyncAllowed(for: apost) { - coordinator.setNeedsSync(for: apost) - } else { - try await coordinator.save(apost) - } - presentingViewController?.dismiss(animated: true) - } catch { - setEnabled(true) - refreshNavigationBarButtons() - } - } - } - - private func didChangeObjects(_ notification: Foundation.Notification, originalPostID: NSManagedObjectID) { - guard let userInfo = notification.userInfo else { return } - - let deletedObjects = ((userInfo[NSDeletedObjectsKey] as? Set) ?? []) - if deletedObjects.contains(where: { $0.objectID == originalPostID }) { - presentingViewController?.dismiss(animated: true) - } - } - - private var changes: RemotePostUpdateParameters { - guard let original = apost.original else { - return RemotePostUpdateParameters() - } - return RemotePostUpdateParameters.changes(from: original, to: apost) - } - - private func deleteRevision() { - apost.original?.deleteRevision() - apost.managedObjectContext.map(ContextManager.shared.saveContextAndWait) - } - - private func setEnabled(_ isEnabled: Bool) { - navigationItem.leftBarButtonItem?.isEnabled = isEnabled - isModalInPresentation = !isEnabled - tableView.tintAdjustmentMode = isEnabled ? .automatic : .dimmed - tableView.isUserInteractionEnabled = isEnabled - } - - private static var cancellablesKey: UInt8 = 0 -} - -extension PostSettingsViewController: UIAdaptivePresentationControllerDelegate { - public func presentationControllerDidDismiss(_ presentationController: UIPresentationController) { - deleteRevision() - } -} - -// MARK: - PostSettingsViewController (Visibility) - -extension PostSettingsViewController { - @objc public func showPostVisibilitySelector() { - let view = PostVisibilityPicker(selection: .init(post: apost)) { [weak self] selection in - guard let self else { return } - - WPAnalytics.track(.editorPostVisibilityChanged, properties: ["via": "settings"]) - - switch selection.type { - case .public, .protected: - if self.apost.original().status == .scheduled { - // Keep it scheduled - } else { - self.apost.status = .publish - } - case .private: - if self.apost.original().status == .scheduled { - DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(300)) { - self.showWarningPostWillBePublishedAlert() - } - } - self.apost.status = .publishPrivate - } - self.apost.password = selection.password.isEmpty ? nil : selection.password - self.navigationController?.popViewController(animated: true) - self.reloadData() - } - let viewController = UIHostingController(rootView: view) - viewController.title = PostVisibilityPicker.title - navigationController?.pushViewController(viewController, animated: true) - } - - private func showWarningPostWillBePublishedAlert() { - let alert = UIAlertController(title: nil, message: Strings.warningPostWillBePublishedAlertMessage, preferredStyle: .alert) - alert.addAction(UIAlertAction(title: SharedStrings.Button.ok, style: .default)) - present(alert, animated: true) - } -} - -// MARK: - PostSettingsViewController (Publish Date) - -extension PostSettingsViewController { - @objc public func showPublishDatePicker() { - var viewModel = PublishSettingsViewModel(post: self.apost) - let viewController = PublishDatePickerViewController.make(viewModel: viewModel) { date in - WPAnalytics.track(.editorPostScheduledChanged, properties: ["via": "settings"]) - viewModel.setDate(date) - } - self.navigationController?.pushViewController(viewController, animated: true) - } -} - -// MARK: - PostSettingsViewController (Page Attributes) - -extension PostSettingsViewController { - @objc public func showParentPageController() { - guard let page = (self.apost as? Page) else { - wpAssertionFailure("post has to be a page") - return - } - Task { - await showParentPageController(for: page) - } - } - - @MainActor - private func showParentPageController(for page: Page) async { - let request = NSFetchRequest(entityName: Page.entityName()) - let filter = PostListFilter.publishedFilter() - request.predicate = filter.predicate(for: apost.blog, author: .everyone) - request.sortDescriptors = filter.sortDescriptors - do { - let context = ContextManager.shared.mainContext - var pages = try await PostRepository().buildPageTree(request: request) - .map { pageID, hierarchyIndex in - let page = try context.existingObject(with: pageID) - page.hierarchyIndex = hierarchyIndex - return page - } - if let index = pages.firstIndex(of: page) { - pages = pages.remove(from: index) - } - let viewController = ParentPageSettingsViewController.make(with: pages, selectedPage: page) - viewController.isModalInPresentation = true - navigationController?.pushViewController(viewController, animated: true) - } catch { - wpAssertionFailure("Failed to fetch pages", userInfo: ["error": "\(error)"]) // This should never happen - } - } - - @objc public func getParentPageTitle() -> String? { - guard let page = (self.apost as? Page) else { - wpAssertionFailure("post has to be a page") - return nil - } - guard let pageID = page.parentID else { - return nil - } - let request = NSFetchRequest(entityName: Page.entityName()) - request.fetchLimit = 1 - request.predicate = NSPredicate(format: "postID == %@", pageID) - guard let parent = try? (page.managedObjectContext?.fetch(request))?.first else { - return nil - } - return parent.titleForDisplay() - } -} - -// MARK: - PostSettingsViewController (Misc) - -extension PostSettingsViewController { -// @objc public func configureFeaturedImageCell(cell: UITableViewCell, viewModel: PostSettingsFeaturedImageViewModel) { -// var configuration = UIHostingConfiguration { -// PostSettingsFeaturedImageRow(post: apost, viewModel: viewModel) { [weak self] in -// self?.showFeaturedImageSelector(cell: cell) -// } -// .environment(\.presentingViewController, self) -// } -// if apost.featuredImage != nil { -// configuration = configuration.margins(.all, 0) -// } -// cell.contentConfiguration = configuration -// cell.selectionStyle = .none -// cell.accessibilityIdentifier = "post_settings_featured_image_cell" -// } - - private func showFeaturedImageSelector(cell: UITableViewCell) { - guard let featuredImage = apost.featuredImage else { return } - let lightboxVC = LightboxViewController(media: featuredImage) - lightboxVC.configureZoomTransition(sourceView: cell.contentView) - present(lightboxVC, animated: true) - } - - @objc public func showPostAuthorSelector() { - let picker = PostAuthorPicker(post: apost) { [weak self] selection in - guard let self else { return } - - self.apost.authorID = selection.id - self.apost.author = selection.displayName - self.apost.authorAvatarURL = selection.avatarURL?.absoluteString - - WPAnalytics.track(.editorPostAuthorChanged, properties: ["via": "settings"]) - self.tableView.reloadData() - } - let hostingController = UIHostingController(rootView: picker) - navigationController?.pushViewController(hostingController, animated: true) - } - - @objc public func showTagsPicker() { - guard let post = apost as? Post else { - return wpAssertionFailure("expected post type") - } - let tagsPickerVC = PostTagPickerViewController(tags: post.tags ?? "", blog: post.blog) - tagsPickerVC.onValueChanged = { value in - WPAnalytics.track(.editorPostTagsChanged, properties: ["via": "settings"]) - post.tags = value - } - WPAnalytics.track(.postSettingsAddTagsShown) - navigationController?.pushViewController(tagsPickerVC, animated: true) - } -} - -// MARK: - PostSettingsViewController (Post Format) - -extension PostSettingsViewController { - @objc public func showPostFormatSelector() { - guard let post = apost as? Post else { - return wpAssertionFailure("expected post type") - } - let pickerView = PostFormatPicker(post: post) { [weak self] format in - guard let self else { return } - if post.postFormatText() != format { - WPAnalytics.track(.editorPostFormatChanged, properties: ["via": "settings"]) - post.setPostFormatText(format) - } - self.navigationController?.popViewController(animated: true) - self.tableView.reloadData() - } - let pickerVC = UIHostingController(rootView: pickerView) - pickerVC.title = PostFormatPicker.title - navigationController?.pushViewController(pickerVC, animated: true) - } -} - -private enum Strings { - static let warningPostWillBePublishedAlertMessage = NSLocalizedString("postSettings.warningPostWillBePublishedAlertMessage", value: "By changing the visibility to 'Private', the post will be published immediately", comment: "An alert message explaning that by changing the visibility to private, the post will be published immediately to your site") -} diff --git a/WordPress/Classes/ViewRelated/Post/PostSettingsViewController.h b/WordPress/Classes/ViewRelated/Post/PostSettingsViewController.h deleted file mode 100644 index c5f9dda4e7a8..000000000000 --- a/WordPress/Classes/ViewRelated/Post/PostSettingsViewController.h +++ /dev/null @@ -1,24 +0,0 @@ -#import -@import WordPressData; - -// TODO: It can be removed when the new editor is released. It only exists to support the "Featured" badge on featured images in Gutenberg mobile. -@protocol FeaturedImageDelegate - -- (void)gutenbergDidRequestFeaturedImageId:(nonnull NSNumber *)mediaID; - -@end - -@interface PostSettingsViewController : UITableViewController - -- (nonnull instancetype)initWithPost:(nonnull AbstractPost *)aPost; - -@property (nonnull, nonatomic, strong, readonly) AbstractPost *apost; -@property (nonatomic) BOOL isStandalone; -@property (nonnull, nonatomic, strong, readonly) NSArray *publicizeConnections; -@property (nonnull, nonatomic, strong, readonly) NSArray *unsupportedConnections; - -@property (nonatomic, weak, nullable) id featuredImageDelegate; - -- (void)reloadData; - -@end diff --git a/WordPress/Classes/ViewRelated/Post/PostSettingsViewController.m b/WordPress/Classes/ViewRelated/Post/PostSettingsViewController.m deleted file mode 100644 index 7b0b1bae33d0..000000000000 --- a/WordPress/Classes/ViewRelated/Post/PostSettingsViewController.m +++ /dev/null @@ -1,875 +0,0 @@ -#import "PostSettingsViewController.h" -#import "PostSettingsViewController_Internal.h" -#import "SettingsSelectionViewController.h" -#import "SharingDetailViewController.h" -#import "MediaService.h" -#ifdef KEYSTONE -#import "Keystone-Swift.h" -#else -#import "WordPress-Swift.h" -#endif -@import WordPressData; - -@import Gridicons; -@import WordPressShared; -@import WordPressKit; -@import WordPressUI; - -typedef NS_ENUM(NSInteger, PostSettingsRow) { - PostSettingsRowCategories = 0, - PostSettingsRowTags, - PostSettingsRowAuthor, - PostSettingsRowPublishDate, - PostSettingsRowPendingReview, - PostSettingsRowVisibility, - PostSettingsRowFormat, - PostSettingsRowFeaturedImage, - PostSettingsRowShareConnection, - PostSettingsRowShareMessage, - PostSettingsRowSlug, - PostSettingsRowExcerpt, - PostSettingsRowSocialNoConnections, - PostSettingsRowSocialRemainingShares, - PostSettingsRowParentPage -}; - -static NSString *const PostSettingsAnalyticsTrackingSource = @"post_settings"; -static NSString *const TableViewFeaturedImageCellIdentifier = @"TableViewFeaturedImageCellIdentifier"; -static NSString *const TableViewToggleCellIdentifier = @"TableViewToggleCellIdentifier"; -static NSString *const TableViewGenericCellIdentifier = @"TableViewGenericCellIdentifier"; - - -@interface PostSettingsViewController () - -@property (nonatomic, strong) AbstractPost *apost; -@property (nonatomic, strong) NSArray *postMetaSectionRows; - -@property (nonatomic, strong) NSArray *publicizeConnections; -@property (nonatomic, strong) NSArray *unsupportedConnections; -@property (nonatomic, strong) NSMutableArray *enabledConnections; - -@property (nonatomic, strong) NSDateFormatter *postDateFormatter; - -#pragma mark - Properties: Services - -@property (nonatomic, strong, readonly) SharingService *sharingService; - -@end - -@implementation PostSettingsViewController - -#pragma mark - Initialization and dealloc - -- (instancetype)initWithPost:(AbstractPost *)aPost -{ - self = [super initWithStyle:UITableViewStyleInsetGrouped]; - if (self) { - self.apost = aPost; - self.unsupportedConnections = @[]; - self.enabledConnections = [NSMutableArray array]; - } - return self; -} - -#pragma mark - UIViewController - -- (void)viewDidLoad -{ - [super viewDidLoad]; - - if ([self.apost isKindOfClass:[Page class]]) { - self.title = NSLocalizedString(@"Page Settings", @"The title of the Page Settings screen."); - } else { - self.title = NSLocalizedString(@"Post Settings", @"The title of the Post Settings screen."); - } - - DDLogInfo(@"%@ %@", self, NSStringFromSelector(_cmd)); - - [WPStyleGuide configureColorsForView:self.view andTableView:self.tableView]; - [WPStyleGuide configureAutomaticHeightRowsFor:self.tableView]; - - [self setupPublicizeConnections]; - - [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:TableViewFeaturedImageCellIdentifier]; - [self.tableView registerClass:[SwitchTableViewCell class] forCellReuseIdentifier:TableViewToggleCellIdentifier]; - [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:TableViewGenericCellIdentifier]; - - self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 0.0, 44.0)]; // add some vertical padding - self.tableView.cellLayoutMarginsFollowReadableWidth = YES; - - // Compensate for the first section's height of 1.0f - self.tableView.contentInset = UIEdgeInsetsMake(-1.0f, 0, 0, 0); - self.tableView.accessibilityIdentifier = @"SettingsTable"; - - [self setupPostDateFormatter]; - - [WPAnalytics track:WPAnalyticsStatPostSettingsShown]; - - [self onViewDidLoad]; -} - -- (void)viewWillAppear:(BOOL)animated -{ - [super viewWillAppear:animated]; - - [self.navigationController setNavigationBarHidden:NO animated:NO]; - [self.navigationController setToolbarHidden:YES]; - - [self setupPublicizeConnections]; // Refresh in case the user disconnects from unsupported services. - [self configureMetaSectionRows]; - [self reloadData]; -} - -- (void)viewDidLayoutSubviews { - [super viewDidLayoutSubviews]; - - [self.tableView sizeToFitFooterView]; -} - -- (void)didReceiveMemoryWarning -{ - DDLogWarn(@"%@ %@", self, NSStringFromSelector(_cmd)); - [super didReceiveMemoryWarning]; -} - -#pragma mark - Additional setup - -- (void)setupPublicizeConnections -{ - // Separate Twitter connections if the service is unsupported. - PublicizeService *twitterService = [PublicizeService lookupPublicizeServiceNamed:@"twitter" - inContext:self.apost.managedObjectContext]; - - if (!twitterService || [twitterService isSupported]) { - return; - } - - NSMutableArray *supportedConnections = [NSMutableArray new]; - NSMutableArray *unsupportedConnections = [NSMutableArray new]; - for (PublicizeConnection *connection in self.post.blog.sortedConnections) { - if ([connection.service isEqualToString:twitterService.serviceID]) { - [unsupportedConnections addObject:connection]; - continue; - } - - [supportedConnections addObject:connection]; - - if (![self.post publicizeConnectionDisabledForKeyringID:connection.keyringConnectionID] - && ![self.enabledConnections containsObject:connection.keyringConnectionID]) { - [self.enabledConnections addObject:connection.keyringConnectionID]; - } - } - - self.publicizeConnections = supportedConnections; - self.unsupportedConnections = unsupportedConnections; -} - -- (void)setupPostDateFormatter -{ - NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; - dateFormatter.dateStyle = NSDateFormatterMediumStyle; - dateFormatter.timeStyle = NSDateFormatterShortStyle; - dateFormatter.timeZone = [self.apost.blog timeZone]; - self.postDateFormatter = dateFormatter; -} - -// sync the latest state of Twitter. -- (void)syncPublicizeServices -{ - __weak __typeof(self) weakSelf = self; - [self.sharingService syncPublicizeServicesForBlog:self.apost.blog success:^{ - [weakSelf setupPublicizeConnections]; - } failure:nil]; -} - -#pragma mark - Instance Methods - -- (void)setApost:(AbstractPost *)apost -{ - if ([apost isEqual:_apost]) { - return; - } - _apost = apost; -} - -- (Post *)post -{ - if ([self.apost isKindOfClass:[Post class]]) { - return (Post *)self.apost; - } - - return nil; -} - -- (void)reloadData -{ - [self configureSections]; - [self.tableView reloadData]; -} - -#pragma mark - UITableView Delegate - -- (void)configureSections -{ - NSNumber *stickyPostSection = @(PostSettingsSectionStickyPost); - NSNumber *disabledTwitterSection = @(PostSettingsSectionDisabledTwitter); - NSNumber *remainingSharesSection = @(PostSettingsSectionSharesRemaining); - NSNumber *shareSection = @(PostSettingsSectionShare); - NSMutableArray *sections = [@[ @(PostSettingsSectionMeta), - @(PostSettingsSectionFeaturedImage), - @(PostSettingsSectionTaxonomy), - stickyPostSection, - shareSection, - disabledTwitterSection, - remainingSharesSection, - @(PostSettingsSectionMoreOptions) ] mutableCopy]; - // Remove sticky post section for self-hosted non Jetpack site - // and non admin user - // - if (![self.apost.blog supports:BlogFeatureWPComRESTAPI] && !self.apost.blog.isAdmin) { - [sections removeObject:stickyPostSection]; - } - - if (self.unsupportedConnections.count == 0) { - [sections removeObject:disabledTwitterSection]; - } - - if ([self numberOfRowsForShareSection] == 0) { - [sections removeObject:shareSection]; - } - - if (![self showRemainingShares]) { - [sections removeObject:remainingSharesSection]; - } - - self.sections = [sections copy]; -} - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView -{ - if (!self.sections) { - [self configureSections]; - } - return [self.sections count]; -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section -{ - NSInteger sec = [[self.sections objectAtIndex:section] integerValue]; - if (sec == PostSettingsSectionTaxonomy) { - return 2; - } else if (sec == PostSettingsSectionMeta) { - return [self.postMetaSectionRows count]; - } else if (sec == PostSettingsSectionFeaturedImage) { - return 1; - } else if (sec == PostSettingsSectionStickyPost) { - return 1; - } else if (sec == PostSettingsSectionShare) { - return [self numberOfRowsForShareSection]; - } else if (sec == PostSettingsSectionDisabledTwitter) { - return self.unsupportedConnections.count; - } else if (sec == PostSettingsSectionSharesRemaining) { - return 1; - } else if (sec == PostSettingsSectionMoreOptions) { - return 3; - } else if (sec == PostSettingsSectionPageAttributes) { - return 1; - } - - return 0; -} - -- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section -{ - NSInteger sec = [[self.sections objectAtIndex:section] integerValue]; - if (sec == PostSettingsSectionTaxonomy) { - return NSLocalizedString(@"Taxonomy", @"Label for the Taxonomy area (categories, keywords, ...) in post settings."); - - } else if (sec == PostSettingsSectionMeta) { - return NSLocalizedString(@"Publish", @"Label for the publish (verb) button. Tapping publishes a draft post."); - - } else if (sec == PostSettingsSectionFeaturedImage) { - return NSLocalizedString(@"Featured Image", @"Label for the Featured Image area in post settings."); - - } else if (sec == PostSettingsSectionStickyPost) { - return NSLocalizedString(@"Mark as Sticky", @"Label for the Mark as Sticky option in post settings."); - - } else if (sec == PostSettingsSectionShare && [self numberOfRowsForShareSection] > 0) { - return NSLocalizedString(@"Jetpack Social", @"Label for the Sharing section in post Settings. Should be the same as WP core."); - - } else if (sec == PostSettingsSectionDisabledTwitter) { - return NSLocalizedStringWithDefaultValue(@"postSettings.section.disabledTwitter.header", - nil, - [NSBundle mainBundle], - @"Twitter Auto-Sharing Is No Longer Available", - @"Section title for the disabled Twitter service in the Post Settings screen"); - - } else if (sec == PostSettingsSectionMoreOptions) { - return NSLocalizedString(@"More Options", @"Label for the More Options area in post settings. Should use the same translation as core WP."); - - } else if (sec == PostSettingsSectionPageAttributes) { - return NSLocalizedStringWithDefaultValue(@"postSettings.section.pageAttributes", nil, [NSBundle mainBundle], @"Page Attributes", @"Section title for Page Attributes"); - } - return nil; -} - -- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section -{ - NSInteger sec = [[self.sections objectAtIndex:section] integerValue]; - if (sec == PostSettingsSectionDisabledTwitter) { - TwitterDeprecationTableFooterView *footerView = [[TwitterDeprecationTableFooterView alloc] init]; - footerView.presentingViewController = self; - footerView.source = @"post_settings"; - - return footerView; - } - - return nil; -} - -- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section -{ - if ([self tableView:tableView numberOfRowsInSection:section] == 0) { - return CGFLOAT_MIN; - } else { - return UITableViewAutomaticDimension; - } -} - -- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section -{ - if ([self tableView:tableView numberOfRowsInSection:section] == 0) { - return CGFLOAT_MIN; - } else { - return UITableViewAutomaticDimension; - } -} - -- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath -{ - return UITableViewAutomaticDimension; -} - -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath -{ - NSInteger sec = [[self.sections objectAtIndex:indexPath.section] integerValue]; - - UITableViewCell *cell; - - if (sec == PostSettingsSectionTaxonomy) { - cell = [self configureTaxonomyCellForIndexPath:indexPath]; - } else if (sec == PostSettingsSectionMeta) { - cell = [self configureMetaPostMetaCellForIndexPath:indexPath]; - } else if (sec == PostSettingsSectionFeaturedImage) { - cell = [self makeFeaturedImageCellForIndexPath:indexPath]; - } else if (sec == PostSettingsSectionStickyPost) { - cell = [self configureStickyPostCellForIndexPath:indexPath]; - } else if (sec == PostSettingsSectionShare || sec == PostSettingsSectionDisabledTwitter) { - cell = [self showNoConnection] ? [self configureNoConnectionCell] : [self configureShareCellForIndexPath:indexPath]; - } else if (sec == PostSettingsSectionSharesRemaining) { - cell = [self configureRemainingSharesCell]; - } else if (sec == PostSettingsSectionMoreOptions) { - cell = [self configureMoreOptionsCellForIndexPath:indexPath]; - } else if (sec == PostSettingsSectionPageAttributes) { - cell = [self configurePageAttributesCellForIndexPath:indexPath]; - } - - return cell ?: [UITableViewCell new]; -} - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath -{ - [tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES]; - - UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; - NSInteger sec = [[self.sections objectAtIndex:indexPath.section] integerValue]; - - if (cell.tag == PostSettingsRowCategories) { - [self showCategoriesSelection]; - } else if (cell.tag == PostSettingsRowTags) { - [self showTagsPicker]; - } else if (cell.tag == PostSettingsRowPublishDate) { - [self showPublishDatePicker]; - } else if (cell.tag == PostSettingsRowVisibility) { - [self showPostVisibilitySelector]; - } else if (cell.tag == PostSettingsRowAuthor) { - [self showPostAuthorSelector]; - } else if (cell.tag == PostSettingsRowFormat) { - [self showPostFormatSelector]; - } else if (sec == PostSettingsSectionDisabledTwitter) { - [self showShareDetailForIndexPath:indexPath]; - } else if (cell.tag == PostSettingsRowShareConnection) { - [self toggleShareConnectionForIndexPath:indexPath]; - } else if (cell.tag == PostSettingsRowShareMessage) { - [self showEditShareMessageController]; - } else if (cell.tag == PostSettingsRowSlug) { - [self showEditSlugController]; - } else if (cell.tag == PostSettingsRowExcerpt) { - [self showEditExcerptController]; - } else if (cell.tag == PostSettingsRowParentPage) { - [self showParentPageController]; - } -} - -- (NSInteger)numberOfRowsForShareSection -{ - if ([self.apost.status isEqualToString:@"private"]) { - return 0; - } - - if (self.apost.blog.supportsPublicize && self.publicizeConnections.count > 0) { - // One row per publicize connection plus an extra row for the publicze message - return self.publicizeConnections.count + 1; - } - return [self showNoConnection] ? 1 : 0; -} - -- (UITableViewCell *)configureTaxonomyCellForIndexPath:(NSIndexPath *)indexPath -{ - UITableViewCell *cell = [self getWPTableViewDisclosureCell]; - - if (indexPath.row == PostSettingsRowCategories) { - // Categories - cell.textLabel.text = NSLocalizedString(@"Categories", @"Label for the categories field. Should be the same as WP core."); - cell.detailTextLabel.text = [NSString decodeXMLCharactersIn:[self.post categoriesText]]; - cell.tag = PostSettingsRowCategories; - cell.accessibilityIdentifier = @"Categories"; - - } else if (indexPath.row == PostSettingsRowTags) { - // Tags - cell.textLabel.text = NSLocalizedString(@"Tags", @"Label for the tags field. Should be the same as WP core."); - cell.detailTextLabel.text = self.post.tags; - cell.tag = PostSettingsRowTags; - cell.accessibilityIdentifier = @"Tags"; - } - - return cell; -} - -- (void)configureMetaSectionRows -{ - NSMutableArray *metaRows = [[NSMutableArray alloc] init]; - - if (self.apost.isMultiAuthorBlog) { - [metaRows addObject:@(PostSettingsRowAuthor)]; - } - - if (self.isDraftOrPending) { - [metaRows addObject:@(PostSettingsRowPendingReview)]; - } else { - [metaRows addObjectsFromArray:@[ - @(PostSettingsRowPublishDate), - @(PostSettingsRowVisibility) - ]]; - } - - self.postMetaSectionRows = [metaRows copy]; -} - -- (UITableViewCell *)configureMetaPostMetaCellForIndexPath:(NSIndexPath *)indexPath -{ - UITableViewCell *cell; - NSInteger row = [[self.postMetaSectionRows objectAtIndex:indexPath.row] integerValue]; - - if (row == PostSettingsRowAuthor) { - // Author - cell = [self getWPTableViewDisclosureCell]; - cell.textLabel.text = NSLocalizedString(@"Author", @"The author of the post or page."); - cell.accessibilityIdentifier = @"SetAuthor"; - cell.detailTextLabel.text = [self.apost authorNameForDisplay]; - cell.tag = PostSettingsRowAuthor; - } else if (row == PostSettingsRowPublishDate) { - // Publish date - cell = [self getWPTableViewDisclosureCellWithIdentifier:@"PostSettingsRowPublishDate"]; - cell.textLabel.text = NSLocalizedString(@"Publish Date", @"Label for the publish date button."); - if (self.apost.dateCreated) { - cell.detailTextLabel.text = [self.postDateFormatter stringFromDate:self.apost.dateCreated]; - } else { - // Should never happen as this field is displayed only for published/scheduled posts - cell.detailTextLabel.text = @""; - } - - if ([self.apost.status isEqualToString:PostStatusPrivate]) { - [cell disable]; - } else { - [cell enable]; - cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; - } - - cell.tag = PostSettingsRowPublishDate; - } else if (row == PostSettingsRowVisibility) { - // Visibility - cell = [self getWPTableViewDisclosureCellWithIdentifier:@"PostSettingsRowVisibility"]; - cell.textLabel.text = NSLocalizedString(@"Visibility", @"The visibility settings of the post. Should be the same as in core WP."); - cell.detailTextLabel.text = [self.apost titleForVisibility]; - cell.tag = PostSettingsRowVisibility; - cell.accessibilityIdentifier = @"Visibility"; - - } else if (row == PostSettingsRowPendingReview) { - // Pending Review - __weak __typeof(self) weakSelf = self; - SwitchTableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:TableViewToggleCellIdentifier]; - cell.name = NSLocalizedStringWithDefaultValue(@"postSettings.pendingReview", nil, [NSBundle mainBundle], @"Pending review", @"The 'Pending Review' setting of the post"); - cell.on = [self.post.status isEqualToString:PostStatusPending]; - cell.onChange = ^(BOOL newValue) { - [WPAnalytics trackEvent:WPAnalyticsEventEditorPostPendingReviewChanged properties:@{@"via": @"settings"}]; - weakSelf.post.status = newValue ? PostStatusPending : PostStatusDraft; - }; - return cell; - } - - return cell; -} - -- (UITableViewCell *)configurePostFormatCellForIndexPath:(NSIndexPath *)indexPath -{ - UITableViewCell *cell = [self getWPTableViewDisclosureCell]; - - cell.textLabel.text = NSLocalizedString(@"Post Format", @"The post formats available for the post. Should be the same as in core WP."); - - if (self.post.postFormatText.length > 0) { - cell.detailTextLabel.text = self.post.postFormatText; - } else { - cell.detailTextLabel.text = NSLocalizedString(@"Unavailable", - @"Message to show in the post-format cell when the post format is not available"); - } - - cell.tag = PostSettingsRowFormat; - cell.accessibilityIdentifier = @"Post Format"; - return cell; -} - -- (UITableViewCell *)makeFeaturedImageCellForIndexPath:(NSIndexPath *)indexPath -{ - UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:TableViewFeaturedImageCellIdentifier forIndexPath:indexPath]; - // [self configureFeaturedImageCellWithCell:cell viewModel:self.featuredImageViewModel]; - cell.tag = PostSettingsRowFeaturedImage; - return cell; -} - -- (UITableViewCell *)configureStickyPostCellForIndexPath:(NSIndexPath *)indexPath -{ - __weak __typeof(self) weakSelf = self; - - SwitchTableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:TableViewToggleCellIdentifier]; - cell.name = NSLocalizedString(@"Stick post to the front page", @"This is the cell title."); - cell.on = self.post.isStickyPost; - cell.onChange = ^(BOOL newValue) { - [WPAnalytics trackEvent:WPAnalyticsEventEditorPostStickyChanged properties:@{@"via": @"settings"}]; - weakSelf.post.isStickyPost = newValue; - }; - return cell; -} - -- (UITableViewCell *)configureSocialCellForIndexPath:(NSIndexPath *)indexPath - connection:(PublicizeConnection *)connection - canEditSharing:(BOOL)canEditSharing - section:(NSInteger)section -{ - UITableViewCell *cell = [self getWPTableViewImageAndAccessoryCell]; - UIImage *image = [[WPStyleGuide socialIconFor:connection.service] resizedTo:CGSizeMake(28.0, 28.0) format: ScalingModeScaleAspectFill]; - [cell.imageView setImage:image]; - cell.imageView.alpha = 1.0; - if (!canEditSharing) { - cell.imageView.alpha = 0.36; - } - cell.textLabel.text = connection.externalDisplay; - cell.textLabel.enabled = canEditSharing; - if (connection.isBroken) { - cell.accessoryView = section == PostSettingsSectionShare ? - [WPStyleGuide sharingCellWarningAccessoryImageView] : - [WPStyleGuide sharingCellErrorAccessoryImageView]; - } else { - UISwitch *switchAccessory = [[UISwitch alloc] initWithFrame:CGRectZero]; - // This interaction is handled at a cell level - switchAccessory.userInteractionEnabled = NO; - switchAccessory.on = ![self.post publicizeConnectionDisabledForKeyringID:connection.keyringConnectionID]; - switchAccessory.enabled = canEditSharing; - cell.accessoryView = switchAccessory; - } - cell.selectionStyle = UITableViewCellSelectionStyleNone; - cell.tag = PostSettingsRowShareConnection; - cell.accessibilityIdentifier = [NSString stringWithFormat:@"%@ %@", connection.service, connection.externalDisplay]; - return cell; -} - -- (UITableViewCell *)configureDisclosureCellWithSharing:(BOOL)canEditSharing -{ - UITableViewCell *cell = [self getWPTableViewDisclosureCell]; - cell.textLabel.text = NSLocalizedString(@"Message", @"Label for the share message field on the post settings."); - cell.textLabel.enabled = canEditSharing; - cell.detailTextLabel.text = self.post.publicizeMessage ? self.post.publicizeMessage : self.post.titleForDisplay; - cell.detailTextLabel.enabled = canEditSharing; - cell.tag = PostSettingsRowShareMessage; - cell.accessibilityIdentifier = @"Customize the message"; - return cell; -} - -- (UITableViewCell *)configureShareCellForIndexPath:(NSIndexPath *)indexPath -{ - UITableViewCell *cell; - BOOL canEditSharing = [self userCanEditSharing]; - NSInteger sec = [[self.sections objectAtIndex:indexPath.section] integerValue]; - NSArray *connections = sec == PostSettingsSectionShare ? self.publicizeConnections : self.unsupportedConnections; - - if (indexPath.row < connections.count) { - PublicizeConnection *connection = connections[indexPath.row]; - if ([RemoteFeature enabled:RemoteFeatureFlagJetpackSocialImprovements]) { - BOOL hasRemainingShares = self.enabledConnections.count < [self remainingSocialShares]; - BOOL isSwitchOn = ![self.post publicizeConnectionDisabledForKeyringID:connection.keyringConnectionID]; - canEditSharing = canEditSharing && (hasRemainingShares || isSwitchOn); - } - cell = [self configureSocialCellForIndexPath:indexPath - connection:connection - canEditSharing:canEditSharing - section:sec]; - } else { - cell = [self configureDisclosureCellWithSharing:canEditSharing]; - } - cell.userInteractionEnabled = canEditSharing; - return cell; -} - -- (UITableViewCell *)configureMoreOptionsCellForIndexPath:(NSIndexPath *)indexPath -{ - if (indexPath.row == 0) { - return [self configurePostFormatCellForIndexPath:indexPath]; - } else if (indexPath.row == 1) { - return [self configureSlugCellForIndexPath:indexPath]; - } else { - return [self configureExcerptCellForIndexPath:indexPath]; - } -} - -- (UITableViewCell *)configureSlugCellForIndexPath:(NSIndexPath *)indexPath -{ - WPTableViewCell *cell = [self getWPTableViewDisclosureCell]; - cell.textLabel.text = NSLocalizedString(@"Slug", @"Label for the slug field. Should be the same as WP core."); - cell.detailTextLabel.text = self.apost.slugForDisplay; - cell.tag = PostSettingsRowSlug; - cell.accessibilityIdentifier = @"Slug"; - return cell; -} - -- (UITableViewCell *)configureExcerptCellForIndexPath:(NSIndexPath *)indexPath -{ - WPTableViewCell *cell = [self getWPTableViewDisclosureCell]; - cell.textLabel.text = NSLocalizedString(@"Excerpt", @"Label for the excerpt field. Should be the same as WP core."); - cell.detailTextLabel.text = self.apost.mt_excerpt; - cell.tag = PostSettingsRowExcerpt; - cell.accessibilityIdentifier = @"Excerpt"; - return cell; -} - -- (WPTableViewCell *)getWPTableViewDisclosureCell { - return [self getWPTableViewDisclosureCellWithIdentifier:@"WPTableViewDisclosureCellIdentifier"]; -} - -- (WPTableViewCell *)getWPTableViewDisclosureCellWithIdentifier:(NSString *)identifier -{ - WPTableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:identifier]; - if (!cell) { - cell = [[WPTableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:identifier]; - cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; - [WPStyleGuide configureTableViewCell:cell]; - } - cell.tag = 0; - return cell; -} - -- (WPTableViewCell *)getWPTableViewImageAndAccessoryCell -{ - static NSString *WPTableViewImageAndAccesoryCellIdentifier = @"WPTableViewImageAndAccesoryCellIdentifier"; - WPTableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:WPTableViewImageAndAccesoryCellIdentifier]; - if (!cell) { - cell = [[WPTableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:WPTableViewImageAndAccesoryCellIdentifier]; - [WPStyleGuide configureTableViewCell:cell]; - } - cell.accessoryView = nil; - cell.imageView.image = nil; - cell.tag = 0; - return cell; -} - -// showPostFormatSelector is now implemented in PostSettingsViewController+Swift.swift - -- (void)toggleShareConnectionForIndexPath:(NSIndexPath *) indexPath -{ - UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; - BOOL isJetpackSocialEnabled = [RemoteFeature enabled:RemoteFeatureFlagJetpackSocialImprovements]; - if (indexPath.row < self.publicizeConnections.count) { - PublicizeConnection *connection = self.publicizeConnections[indexPath.row]; - if (connection.isBroken) { - SharingDetailViewController *controller = [[SharingDetailViewController alloc] initWithBlog:self.post.blog - publicizeConnection:connection]; - [self.navigationController pushViewController:controller animated:YES]; - } else { - UISwitch *cellSwitch = (UISwitch *)cell.accessoryView; - [cellSwitch setOn:!cellSwitch.on animated:YES]; - if (cellSwitch.on) { - [self.post enablePublicizeConnectionWithKeyringID:connection.keyringConnectionID]; - - if (isJetpackSocialEnabled) { - [self.enabledConnections addObject:connection.keyringConnectionID]; - [self reloadSocialSectionComparingValue:[self remainingSocialShares]]; - } - } else { - [self.post disablePublicizeConnectionWithKeyringID:connection.keyringConnectionID]; - - if (isJetpackSocialEnabled) { - [self.enabledConnections removeObject:connection.keyringConnectionID]; - [self reloadSocialSectionComparingValue:[self remainingSocialShares] - 1]; - } - } - if (isJetpackSocialEnabled) { - [WPAnalytics trackEvent:WPAnalyticsEventJetpackSocialConnectionToggled - properties:@{@"source": PostSettingsAnalyticsTrackingSource, - @"value": cellSwitch.on ? @"true" : @"false"}]; - } - } - } -} - -- (void)showShareDetailForIndexPath:(NSIndexPath *)indexPath -{ - if (indexPath.row >= self.unsupportedConnections.count) { - return; - } - - PublicizeConnection *connection = self.unsupportedConnections[indexPath.row]; - SharingDetailViewController *controller = [[SharingDetailViewController alloc] initWithBlog:self.apost.blog - publicizeConnection:connection]; - [self.navigationController pushViewController:controller animated:YES]; -} - -- (void)showEditShareMessageController -{ - NSString *text = !self.post.publicizeMessage ? self.post.titleForDisplay : self.post.publicizeMessage; - - SettingsMultiTextViewController *vc = [[SettingsMultiTextViewController alloc] initWithText:text - placeholder:nil - hint:NSLocalizedString(@"Customize the message you want to share.\nIf you don't add your own text here, we'll use the post's title as the message.", @"Hint displayed when the user is customizing the share message.") - isPassword:NO]; - vc.title = NSLocalizedString(@"Customize the message", @"Title for the edition of the share message."); - vc.onValueChanged = ^(NSString *value) { - if (value.length) { - self.post.publicizeMessage = value; - } else { - self.post.publicizeMessage = nil; - } - [self.tableView reloadData]; - }; - [self.navigationController pushViewController:vc animated:YES]; -} - -- (void)showEditSlugController -{ - SettingsMultiTextViewController *vc = [[SettingsMultiTextViewController alloc] initWithText:self.apost.slugForDisplay - placeholder:nil - hint:NSLocalizedString(@"The slug is the URL-friendly version of the post title.", @"Should be the same as the text displayed if the user clicks the (i) in Slug in Calypso.") - isPassword:NO]; - vc.title = NSLocalizedString(@"Slug", @"Label for the slug field. Should be the same as WP core."); - vc.autocapitalizationType = UITextAutocapitalizationTypeNone; - vc.onValueChanged = ^(NSString *value) { - [WPAnalytics trackEvent:WPAnalyticsEventEditorPostSlugChanged properties:@{@"via": @"settings"}]; - self.apost.wp_slug = value; - [self.tableView reloadData]; - }; - [self.navigationController pushViewController:vc animated:YES]; -} - -- (void)showEditExcerptController -{ - SettingsMultiTextViewController *vc = [[SettingsMultiTextViewController alloc] initWithText:self.apost.mt_excerpt - placeholder:nil - hint:NSLocalizedString(@"Excerpts are optional hand-crafted summaries of your content.", @"Should be the same as the text displayed if the user clicks the (i) in Calypso.") - isPassword:NO]; - vc.title = NSLocalizedString(@"Excerpt", @"Label for the excerpt field. Should be the same as WP core."); - vc.onValueChanged = ^(NSString *value) { - if (self.apost.mt_excerpt != value) { - [WPAnalytics trackEvent:WPAnalyticsEventEditorPostExcerptChanged properties:@{@"via": @"settings"}]; - } - - self.apost.mt_excerpt = value; - [self.tableView reloadData]; - }; - [self.navigationController pushViewController:vc animated:YES]; -} - -- (void)showCategoriesSelection -{ - PostCategoriesViewController *controller = [[PostCategoriesViewController alloc] initWithBlog:self.post.blog - currentSelection:[self.post.categories allObjects] - selectionMode:CategoriesSelectionModePost]; - controller.delegate = self; - [self.navigationController pushViewController:controller animated:YES]; -} - -#pragma mark - Jetpack Social - -- (UITableViewCell *)configureGenericCellWith:(UIView *)view { - UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:TableViewGenericCellIdentifier]; - for (UIView *subview in cell.contentView.subviews) { - [subview removeFromSuperview]; - } - [cell.contentView addSubview:view]; - [cell.contentView pinSubviewToAllEdges:view]; - return cell; -} - -- (UITableViewCell *)configureNoConnectionCell -{ - UITableViewCell *cell = [self configureGenericCellWith:[self createNoConnectionView]]; - cell.tag = PostSettingsRowSocialNoConnections; - return cell; -} - -- (UITableViewCell *)configureRemainingSharesCell -{ - UITableViewCell *cell = [self configureGenericCellWith:[self createRemainingSharesView]]; - cell.tag = PostSettingsRowSocialRemainingShares; - return cell; -} - -- (void)reloadSocialSectionComparingValue:(NSUInteger)value -{ - if (self.enabledConnections.count == value) { - NSUInteger sharingSection = [self.sections indexOfObject:@(PostSettingsSectionShare)]; - NSIndexSet *sharingSectionSet = [NSIndexSet indexSetWithIndex:sharingSection]; - [self.tableView reloadSections:sharingSectionSet withRowAnimation:UITableViewRowAnimationNone]; - } -} - -// MARK: - Page Attributes - -- (UITableViewCell *)configurePageAttributesCellForIndexPath:(NSIndexPath *)indexPath -{ - return [self configureParentPageCell]; -} - -- (UITableViewCell *)configureParentPageCell -{ - UITableViewCell *cell = [self getWPTableViewDisclosureCell]; - cell.textLabel.text = NSLocalizedStringWithDefaultValue(@"postSettings.parentPage", nil, [NSBundle mainBundle], @"Parent page", @"The 'Parent Page' setting of the post"); - cell.detailTextLabel.text = [self getParentPageTitle]; - cell.tag = PostSettingsRowParentPage; - cell.accessibilityIdentifier = @"Parent"; - return cell; -} - -#pragma mark - PostCategoriesViewControllerDelegate - -- (void)postCategoriesViewController:(PostCategoriesViewController *)controller didUpdateSelectedCategories:(NSSet *)categories -{ - [WPAnalytics trackEvent:WPAnalyticsEventEditorPostCategoryChanged properties:@{@"via": @"settings"}]; - - // Save changes. - self.post.categories = [categories mutableCopy]; - if (!self.isStandalone) { - [self.post save]; - } -} - -@end diff --git a/WordPress/Classes/ViewRelated/Post/PostSettingsViewController_Internal.h b/WordPress/Classes/ViewRelated/Post/PostSettingsViewController_Internal.h deleted file mode 100644 index 7be46a2547ac..000000000000 --- a/WordPress/Classes/ViewRelated/Post/PostSettingsViewController_Internal.h +++ /dev/null @@ -1,20 +0,0 @@ -#import "PostSettingsViewController.h" - -typedef enum { - PostSettingsSectionTaxonomy = 0, - PostSettingsSectionMeta, - PostSettingsSectionFeaturedImage, - PostSettingsSectionShare, - PostSettingsSectionStickyPost, - PostSettingsSectionDisabledTwitter, // NOTE: Clean up when Twitter has been removed from Publicize services. - PostSettingsSectionSharesRemaining, - PostSettingsSectionGeolocation, - PostSettingsSectionMoreOptions, - PostSettingsSectionPageAttributes -} PostSettingsSection; - -@interface PostSettingsViewController () - -@property (nonnull, nonatomic, strong) NSArray *sections; - -@end diff --git a/WordPress/Classes/ViewRelated/Post/Scheduling/PublishDatePickerViewController.swift b/WordPress/Classes/ViewRelated/Post/Scheduling/PublishDatePickerViewController.swift index 5b2ee37f51c2..0fe4c8250e0c 100644 --- a/WordPress/Classes/ViewRelated/Post/Scheduling/PublishDatePickerViewController.swift +++ b/WordPress/Classes/ViewRelated/Post/Scheduling/PublishDatePickerViewController.swift @@ -39,17 +39,6 @@ final class PublishDatePickerViewController: UIHostingController Void) -> PublishDatePickerViewController { - PublishDatePickerViewController(configuration: .init( - date: viewModel.date, - isRequired: viewModel.isRequired, - timeZone: viewModel.timeZone, - updated: onDateUpdated - )) - } -} - struct PublishDatePickerView: View { @State var configuration: PublishDatePickerConfiguration diff --git a/WordPress/Classes/ViewRelated/Post/Scheduling/PublishSettingsViewController.swift b/WordPress/Classes/ViewRelated/Post/Scheduling/PublishSettingsViewController.swift deleted file mode 100644 index 1a06c186717b..000000000000 --- a/WordPress/Classes/ViewRelated/Post/Scheduling/PublishSettingsViewController.swift +++ /dev/null @@ -1,47 +0,0 @@ -import Foundation -import WordPressData -import WordPressShared - -struct PublishSettingsViewModel { - enum State { - case scheduled(Date) - case published(Date) - case immediately - - init(post: AbstractPost) { - if let date = post.dateCreated { - self = date > .now ? .scheduled(date) : .published(date) - } else { - self = .immediately - } - } - } - - private(set) var state: State - let timeZone: TimeZone - - private let post: AbstractPost - - var isRequired: Bool { post.original().isStatus(in: [.publish, .scheduled]) } - - init(post: AbstractPost) { - state = State(post: post) - - self.post = post - timeZone = post.blog.timeZone ?? TimeZone.current - } - - var date: Date? { - switch state { - case .scheduled(let date), .published(let date): - return date - case .immediately: - return nil - } - } - - mutating func setDate(_ date: Date?) { - post.dateCreated = date - state = State(post: post) - } -} diff --git a/WordPress/WordPress.xcodeproj/project.pbxproj b/WordPress/WordPress.xcodeproj/project.pbxproj index 275b22af2a9e..95994a875704 100644 --- a/WordPress/WordPress.xcodeproj/project.pbxproj +++ b/WordPress/WordPress.xcodeproj/project.pbxproj @@ -1127,8 +1127,6 @@ ViewRelated/Comments/Controllers/CommentsViewController.h, ViewRelated/Menus/Controllers/MenuItemsViewController.h, ViewRelated/Menus/Controllers/MenusViewController.h, - ViewRelated/Pages/PageSettingsViewController.h, - ViewRelated/Post/PostSettingsViewController.h, ViewRelated/Stats/StatsViewController.h, ViewRelated/Suggestions/SuggestionsTableView.h, ViewRelated/Suggestions/SuggestionsTableViewCell.h,