diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt index 58f147b66cc7..18006aac0ffa 100644 --- a/RELEASE-NOTES.txt +++ b/RELEASE-NOTES.txt @@ -1,6 +1,6 @@ 24.9 ----- - +* [*] Add "Parent Page" to "Page Settings" [#23136] 24.8 ----- diff --git a/WordPress/Classes/Services/PostRepository.swift b/WordPress/Classes/Services/PostRepository.swift index 952983ab986c..761bab90473b 100644 --- a/WordPress/Classes/Services/PostRepository.swift +++ b/WordPress/Classes/Services/PostRepository.swift @@ -459,6 +459,28 @@ final class PostRepository { } } } + + @MainActor + func buildPageTree(pageIDs: [TaggedManagedObjectID]? = nil, request: NSFetchRequest? = nil) async throws -> [(pageID: TaggedManagedObjectID, hierarchyIndex: Int)] { + assert(pageIDs != nil || request != nil, "`pageIDs` and `request` can not both be nil") + + let coreDataStack = ContextManager.shared + return try await coreDataStack.performQuery { context in + var pages = [Page]() + + if let pageIDs { + pages = try pageIDs.map(context.existingObject(with:)) + } else if let request { + pages = try context.fetch(request) + } + + pages = pages.setHomePageFirst() + + // The `hierarchyIndex` is not a managed property, so it needs to be returend along with the page object id. + return PageTree.hierarchyList(of: pages) + .map { (TaggedManagedObjectID($0), $0.hierarchyIndex) } + } + } } private extension PostRepository { diff --git a/WordPress/Classes/ViewRelated/Pages/PageListViewController+Menu.swift b/WordPress/Classes/ViewRelated/Pages/PageListViewController+Menu.swift index b5ded19e1bc8..4fbe0441b18d 100644 --- a/WordPress/Classes/ViewRelated/Pages/PageListViewController+Menu.swift +++ b/WordPress/Classes/ViewRelated/Pages/PageListViewController+Menu.swift @@ -60,13 +60,6 @@ extension PageListViewController: InteractivePostViewDelegate { PostSettingsViewController.showStandaloneEditor(for: post, from: self) } - func setParent(for apost: AbstractPost) { - guard let page = apost as? Page else { return } - Task { - await setParentPage(for: page) - } - } - func setHomepage(for apost: AbstractPost) { guard let page = apost as? Page else { return } WPAnalytics.track(.postListSetAsPostsPageAction) diff --git a/WordPress/Classes/ViewRelated/Pages/PageListViewController.swift b/WordPress/Classes/ViewRelated/Pages/PageListViewController.swift index 6499eb560d17..a4859fd79f22 100644 --- a/WordPress/Classes/ViewRelated/Pages/PageListViewController.swift +++ b/WordPress/Classes/ViewRelated/Pages/PageListViewController.swift @@ -217,7 +217,7 @@ final class PageListViewController: AbstractPostListViewController { let pageIDs = pages.map { TaggedManagedObjectID($0) } do { - self.pages = try await buildPageTree(pageIDs: pageIDs) + self.pages = try await PostRepository().buildPageTree(pageIDs: pageIDs) .map { pageID, hierarchyIndex in let page = try coreDataStack.mainContext.existingObject(with: pageID) page.hierarchyIndex = hierarchyIndex @@ -234,29 +234,6 @@ final class PageListViewController: AbstractPostListViewController { refreshResults() } - /// Build page hierachy in background, which should not take long (less than 2 seconds for 6000+ pages). - @MainActor - func buildPageTree(pageIDs: [TaggedManagedObjectID]? = nil, request: NSFetchRequest? = nil) async throws -> [(pageID: TaggedManagedObjectID, hierarchyIndex: Int)] { - assert(pageIDs != nil || request != nil, "`pageIDs` and `request` can not both be nil") - - let coreDataStack = ContextManager.shared - return try await coreDataStack.performQuery { context in - var pages = [Page]() - - if let pageIDs { - pages = try pageIDs.map(context.existingObject(with:)) - } else if let request { - pages = try context.fetch(request) - } - - pages = pages.setHomePageFirst() - - // The `hierarchyIndex` is not a managed property, so it needs to be returend along with the page object id. - return PageTree.hierarchyList(of: pages) - .map { (TaggedManagedObjectID($0), $0.hierarchyIndex) } - } - } - override func syncContentEnded(_ syncHelper: WPContentSyncHelper) { guard syncHelper.hasMoreContent else { super.syncContentEnded(syncHelper) @@ -429,40 +406,6 @@ final class PageListViewController: AbstractPostListViewController { // MARK: - Cell Action Handling - @MainActor - func setParentPage(for page: Page) async { - let request = NSFetchRequest(entityName: Page.entityName()) - let filter = PostListFilter.publishedFilter() - request.predicate = filter.predicate(for: blog, author: .everyone) - request.sortDescriptors = filter.sortDescriptors - do { - let context = ContextManager.shared.mainContext - var pages = try await 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.navigationController(with: pages, selectedPage: page, onClose: { [weak self] in - self?.updateAndPerformFetchRequestRefreshingResults() - }, onSuccess: { [weak self] in - self?.handleSetParentSuccess() - } ) - present(viewController, animated: true) - } catch { - assertionFailure("Failed to fetch pages: \(error)") // This should never happen - } - } - - private func handleSetParentSuccess() { - let setParentSuccefullyNotice = NSLocalizedString("Parent page successfully updated.", comment: "Message informing the user that their pages parent has been set successfully") - let notice = Notice(title: setParentSuccefullyNotice, feedbackType: .success) - ActionDispatcher.global.dispatch(NoticeAction.post(notice)) - } - func setPageAsHomepage(_ page: Page) { guard let homePageID = page.postID?.intValue else { return } beginRefreshingManually() diff --git a/WordPress/Classes/ViewRelated/Pages/PageMenuViewModelTests.swift b/WordPress/Classes/ViewRelated/Pages/PageMenuViewModelTests.swift index 40d53bebc3bc..3a5617ed54c2 100644 --- a/WordPress/Classes/ViewRelated/Pages/PageMenuViewModelTests.swift +++ b/WordPress/Classes/ViewRelated/Pages/PageMenuViewModelTests.swift @@ -26,7 +26,7 @@ final class PageMenuViewModelTests: CoreDataTestCase { [.view], [.moveToDraft, .duplicate, .share], [.blaze], - [.setParent, .setHomepage, .setPostsPage], + [.setHomepage, .setPostsPage], [.stats, .settings], [.trash] ] @@ -54,7 +54,7 @@ final class PageMenuViewModelTests: CoreDataTestCase { let expectedButtons: [[AbstractPostButton]] = [ [.view], [.moveToDraft, .duplicate, .share], - [.setParent, .setHomepage, .setPostsPage], + [.setHomepage, .setPostsPage], [.stats, .settings], [.trash] ] @@ -82,7 +82,7 @@ final class PageMenuViewModelTests: CoreDataTestCase { let expectedButtons: [[AbstractPostButton]] = [ [.view], [.moveToDraft, .duplicate, .share], - [.setParent, .setHomepage, .setPostsPage], + [.setHomepage, .setPostsPage], [.settings], [.trash] ] @@ -111,7 +111,7 @@ final class PageMenuViewModelTests: CoreDataTestCase { [.view], [.duplicate, .share], [.blaze], - [.setParent, .setPostsPage], + [.setPostsPage], [.stats, .settings] ] expect(buttons).to(equal(expectedButtons)) @@ -139,7 +139,7 @@ final class PageMenuViewModelTests: CoreDataTestCase { [.view], [.moveToDraft, .duplicate, .share], [.blaze], - [.setParent, .setHomepage, .setRegularPage], + [.setHomepage, .setRegularPage], [.stats, .settings], [.trash] ] @@ -160,7 +160,6 @@ final class PageMenuViewModelTests: CoreDataTestCase { let expectedButtons: [[AbstractPostButton]] = [ [.view], [.publish, .duplicate], - [.setParent], [.settings], [.trash] ] @@ -181,7 +180,6 @@ final class PageMenuViewModelTests: CoreDataTestCase { let expectedButtons: [[AbstractPostButton]] = [ [.view], [.moveToDraft], - [.setParent], [.settings], [.trash] ] diff --git a/WordPress/Classes/ViewRelated/Pages/PageSettingsViewController.m b/WordPress/Classes/ViewRelated/Pages/PageSettingsViewController.m index 8aa88296996f..21e7c719df7e 100644 --- a/WordPress/Classes/ViewRelated/Pages/PageSettingsViewController.m +++ b/WordPress/Classes/ViewRelated/Pages/PageSettingsViewController.m @@ -10,7 +10,11 @@ @implementation PageSettingsViewController - (void)configureSections { - self.sections = @[@(PostSettingsSectionMeta),@(PostSettingsSectionFeaturedImage)]; + self.sections = @[ + @(PostSettingsSectionMeta), + @(PostSettingsSectionFeaturedImage), + @(PostSettingsSectionPageAttributes) + ]; } - (Page *)page diff --git a/WordPress/Classes/ViewRelated/Pages/Pages.storyboard b/WordPress/Classes/ViewRelated/Pages/Pages.storyboard index 4c0fddd24d2a..1bbcb898b47a 100644 --- a/WordPress/Classes/ViewRelated/Pages/Pages.storyboard +++ b/WordPress/Classes/ViewRelated/Pages/Pages.storyboard @@ -1,32 +1,16 @@ - + - + - - - - - - - - - - - - - - - - - + @@ -35,18 +19,17 @@ - - - + + - + - + @@ -55,21 +38,8 @@ - - - - - - - - - - - - + - - @@ -79,9 +49,4 @@ - - - - - diff --git a/WordPress/Classes/ViewRelated/Pages/ParentPageSettingsViewController.swift b/WordPress/Classes/ViewRelated/Pages/ParentPageSettingsViewController.swift index d89178b77e95..01535311a6b4 100644 --- a/WordPress/Classes/ViewRelated/Pages/ParentPageSettingsViewController.swift +++ b/WordPress/Classes/ViewRelated/Pages/ParentPageSettingsViewController.swift @@ -32,22 +32,12 @@ private struct Row: ImmuTableRow { } } -extension Row: Equatable { - static func == (lhs: Row, rhs: Row) -> Bool { - return lhs.page?.postID == rhs.page?.postID - } -} - class ParentPageSettingsViewController: UIViewController { var onClose: (() -> Void)? - var onSuccess: (() -> Void)? - @IBOutlet private var cancelButton: UIBarButtonItem! - @IBOutlet private var doneButton: UIBarButtonItem! @IBOutlet private var tableView: UITableView! @IBOutlet private var searchBar: UISearchBar! - private let postService = PostService(managedObjectContext: ContextManager.sharedInstance().mainContext) private lazy var noResultsViewController = NoResultsViewController.controller() private var isSearching = false private var sections: [ImmuTableSection] { @@ -59,14 +49,6 @@ class ParentPageSettingsViewController: UIViewController { private var rows: [ImmuTableSection]! private var filteredRows: [ImmuTableSection]! private var selectedPage: Page! - private var originalRow: Row? - private var selectedRow: Row? { - didSet { - doneButton.isEnabled = selectedRow != originalRow - } - } - - private var selectedParentID: NSNumber? override func viewDidLoad() { super.viewDidLoad() @@ -89,9 +71,6 @@ class ParentPageSettingsViewController: UIViewController { func set(pages: [Page], for page: Page) { selectedPage = page - selectedParentID = selectedPage.parentID - originalRow = originalRow(with: pages) - selectedRow = originalRow filteredRows = [] @@ -103,15 +82,10 @@ class ParentPageSettingsViewController: UIViewController { // MARK: - Private methods private func setupUI() { - navigationItem.title = NSLocalizedString("Set Parent", comment: "Navigation title displayed on the navigation bar") - - cancelButton.title = NSLocalizedString("Cancel", comment: "Text displayed by the left navigation button title") - doneButton.title = NSLocalizedString("Done", comment: "Text displayed by the right navigation button title") + navigationItem.title = NSLocalizedString("parentPageSettings.title", value: "Parent Page", comment: "Navigation title displayed on the navigation bar") searchBar.delegate = self - WPStyleGuide.setRightBarButtonItemWithCorrectSpacing(doneButton, for: navigationItem) - WPStyleGuide.setLeftBarButtonItemWithCorrectSpacing(cancelButton, for: navigationItem) WPStyleGuide.configureSearchBar(searchBar) setupTableView() @@ -173,20 +147,12 @@ class ParentPageSettingsViewController: UIViewController { tableView.reloadSections(sections, with: animation) } - private func updatePage(_ completion: ((_ page: AbstractPost?, _ error: Error?) -> Void)?) { - postService.uploadPost(selectedPage, success: { uploadedPost in - completion?(uploadedPost, nil) - }) { error in - completion?(nil, error) - } - } - private func originalRow(with pages: [Page]) -> Row? { if selectedPage.isTopLevelPage { return Row() } - guard let parent = (pages.first { $0.postID == selectedParentID }) else { + guard let parent = (pages.first { $0.postID == selectedPage.parentID }) else { return nil } @@ -216,70 +182,6 @@ class ParentPageSettingsViewController: UIViewController { noResultsViewController.removeFromView() } } - - private func dismiss() { - onClose?() - dismiss(animated: true) - } - - // MARK: IBAction - - @IBAction func doneAction(_ sender: UIBarButtonItem) { - WPAnalytics.track(.pageSetParentDonePressed) - - SVProgressHUD.setDefaultMaskType(.clear) - SVProgressHUD.show(withStatus: NSLocalizedString("Updating...", - comment: "Text displayed in HUD while a draft or scheduled post is being updated.")) - - selectedParentID = selectedRow?.page?.postID - - if FeatureFlag.syncPublishing.enabled { - Task { - await self.saveChanges() - } - } else { - _saveChanges() - } - } - - @MainActor - private func saveChanges() async { - do { - var changes = RemotePostUpdateParameters() - // - warning: `.some` is important to make sure the parameter is included - changes.parentPageID = .some(selectedParentID?.intValue) - try await PostCoordinator.shared._update(selectedPage.original(), changes: changes) - - await SVProgressHUD.dismiss() - self.dismiss() - self.onSuccess?() - } catch { - await SVProgressHUD.dismiss() - } - } - - /// - warning: deprecated (kahu-offline-mode) - private func _saveChanges() { - let parentId: NSNumber? = selectedPage.parentID - selectedPage.parentID = selectedRow?.page?.postID - updatePage { [weak self] (_, error) in - SVProgressHUD.dismiss() - - if let error = error { - DDLogError("Error publishing post: \(error.localizedDescription)") - SVProgressHUD.showDismissibleError(withStatus: NSLocalizedString("Error occurred\nduring saving", - comment: "Text displayed in HUD after attempting to save a draft post and an error occurred.")) - self?.selectedPage.parentID = parentId - } else { - self?.dismiss() - self?.onSuccess?() - } - } - } - - @IBAction func cancelAction(_ sender: UIBarButtonItem) { - dismiss() - } } extension ParentPageSettingsViewController: UITableViewDataSource { @@ -297,7 +199,7 @@ extension ParentPageSettingsViewController: UITableViewDataSource { } let cell: CheckmarkTableViewCell = self.cell(for: tableView, at: indexPath, identifier: row.reusableIdentifier) - cell.on = selectedRow == row + cell.on = row.page?.postID == selectedPage.parentID row.configureCell(cell) return cell } @@ -316,12 +218,10 @@ extension ParentPageSettingsViewController: UITableViewDelegate { } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - guard let row = sections[indexPath.section].rows[indexPath.row] as? Row, - row != selectedRow else { + guard let row = sections[indexPath.section].rows[indexPath.row] as? Row else { return } - - selectedRow = row + selectedPage.parentID = row.page?.postID tableView.reloadData() } } @@ -329,18 +229,14 @@ extension ParentPageSettingsViewController: UITableViewDelegate { /// ParentPageSettingsViewController class constructor // extension ParentPageSettingsViewController { - class func navigationController(with pages: [Page], selectedPage: Page, onClose: (() -> Void)? = nil, onSuccess: (() -> Void)? = nil) -> UINavigationController { - let storyBoard = UIStoryboard(name: "Pages", bundle: Bundle.main) - guard let controller = storyBoard.instantiateViewController(withIdentifier: "ParentPageSettings") as? UINavigationController else { - fatalError("A navigation view controller is required for Parent Page Settings") - } - guard let parentPageSettingsViewController = controller.viewControllers.first as? ParentPageSettingsViewController else { - fatalError("A ParentPageSettingsViewController is required for Parent Page Settings") + class func make(with pages: [Page], selectedPage: Page, onClose: @escaping () -> Void) -> UIViewController { + let storyboard = UIStoryboard(name: "Pages", bundle: Bundle.main) + guard let viewController = storyboard.instantiateViewController(withIdentifier: "ParentPageSettings") as? ParentPageSettingsViewController else { + fatalError("A ParentPageSettingsViewController view controller is required for Parent Page Settings") } - parentPageSettingsViewController.set(pages: pages, for: selectedPage) - parentPageSettingsViewController.onClose = onClose - parentPageSettingsViewController.onSuccess = onSuccess - return controller + viewController.set(pages: pages, for: selectedPage) + viewController.onClose = onClose + return viewController } } diff --git a/WordPress/Classes/ViewRelated/Post/AbstractPostMenuHelper.swift b/WordPress/Classes/ViewRelated/Post/AbstractPostMenuHelper.swift index 731e4fcde002..836d58f004b8 100644 --- a/WordPress/Classes/ViewRelated/Post/AbstractPostMenuHelper.swift +++ b/WordPress/Classes/ViewRelated/Post/AbstractPostMenuHelper.swift @@ -105,7 +105,6 @@ extension AbstractPostButton: AbstractPostMenuAction { case .blaze: return UIImage(systemName: "flame") case .comments: return UIImage(systemName: "bubble.right") case .settings: return UIImage(systemName: "gearshape") - case .setParent: return UIImage(systemName: "text.append") case .setHomepage: return UIImage(systemName: "house") case .setPostsPage: return UIImage(systemName: "text.word.spacing") case .setRegularPage: return UIImage(systemName: "arrow.uturn.backward") @@ -141,7 +140,6 @@ extension AbstractPostButton: AbstractPostMenuAction { case .blaze: return Strings.blaze case .comments: return Strings.comments case .settings: return Strings.settings - case .setParent: return Strings.setParent case .setHomepage: return Strings.setHomepage case .setPostsPage: return Strings.setPostsPage case .setRegularPage: return Strings.setRegularPage @@ -177,8 +175,6 @@ extension AbstractPostButton: AbstractPostMenuAction { delegate.comments(post) case .settings: delegate.showSettings(for: post) - case .setParent: - delegate.setParent(for: post) case .setHomepage: delegate.setHomepage(for: post) case .setPostsPage: @@ -205,7 +201,6 @@ extension AbstractPostButton: AbstractPostMenuAction { static let retry = NSLocalizedString("posts.retry.actionTitle", value: "Retry", comment: "Retry uploading the post.") static let share = NSLocalizedString("posts.share.actionTitle", value: "Share", comment: "Share the post.") static let blaze = NSLocalizedString("posts.blaze.actionTitle", value: "Promote with Blaze", comment: "Promote the post with Blaze.") - static let setParent = NSLocalizedString("posts.setParent.actionTitle", value: "Set parent", comment: "Set the parent page for the selected page.") static let setHomepage = NSLocalizedString("posts.setHomepage.actionTitle", value: "Set as homepage", comment: "Set the selected page as the homepage.") static let setPostsPage = NSLocalizedString("posts.setPostsPage.actionTitle", value: "Set as posts page", comment: "Set the selected page as a posts page.") static let setRegularPage = NSLocalizedString("posts.setRegularPage.actionTitle", value: "Set as regular page", comment: "Set the selected page as a regular page.") diff --git a/WordPress/Classes/ViewRelated/Post/AbstractPostMenuViewModel.swift b/WordPress/Classes/ViewRelated/Post/AbstractPostMenuViewModel.swift index 2295e843a906..7690f451a0b8 100644 --- a/WordPress/Classes/ViewRelated/Post/AbstractPostMenuViewModel.swift +++ b/WordPress/Classes/ViewRelated/Post/AbstractPostMenuViewModel.swift @@ -31,7 +31,6 @@ enum AbstractPostButton: Equatable { /// Specific to pages case pageAttributes - case setParent case setHomepage case setPostsPage case setRegularPage diff --git a/WordPress/Classes/ViewRelated/Post/InteractivePostViewDelegate.swift b/WordPress/Classes/ViewRelated/Post/InteractivePostViewDelegate.swift index 372fccecf8e0..3cfd06c9bf7b 100644 --- a/WordPress/Classes/ViewRelated/Post/InteractivePostViewDelegate.swift +++ b/WordPress/Classes/ViewRelated/Post/InteractivePostViewDelegate.swift @@ -15,14 +15,12 @@ protocol InteractivePostViewDelegate: AnyObject { func blaze(_ post: AbstractPost) func comments(_ post: AbstractPost) func showSettings(for post: AbstractPost) - func setParent(for post: AbstractPost) func setHomepage(for post: AbstractPost) func setPostsPage(for post: AbstractPost) func setRegularPage(for post: AbstractPost) } extension InteractivePostViewDelegate { - func setParent(for post: AbstractPost) {} func setHomepage(for post: AbstractPost) {} func setPostsPage(for post: AbstractPost) {} func setRegularPage(for post: AbstractPost) {} diff --git a/WordPress/Classes/ViewRelated/Post/PageMenuViewModel.swift b/WordPress/Classes/ViewRelated/Post/PageMenuViewModel.swift index 16eda0fd0253..cba3dc70036b 100644 --- a/WordPress/Classes/ViewRelated/Post/PageMenuViewModel.swift +++ b/WordPress/Classes/ViewRelated/Post/PageMenuViewModel.swift @@ -110,8 +110,6 @@ final class PageMenuViewModel: AbstractPostMenuViewModel { return AbstractPostButtonSection(buttons: buttons) } - buttons.append(.setParent) - guard page.status == .publish else { return AbstractPostButtonSection(buttons: buttons) } diff --git a/WordPress/Classes/ViewRelated/Post/PostSettingsViewController+Swift.swift b/WordPress/Classes/ViewRelated/Post/PostSettingsViewController+Swift.swift index d6a7b30c2047..93af5cf6eb91 100644 --- a/WordPress/Classes/ViewRelated/Post/PostSettingsViewController+Swift.swift +++ b/WordPress/Classes/ViewRelated/Post/PostSettingsViewController+Swift.swift @@ -178,6 +178,65 @@ extension PostSettingsViewController: UIAdaptivePresentationControllerDelegate { } } +// MARK: - PostSettingsViewController (Page Attributes) + +extension PostSettingsViewController { + @objc 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) { [weak self] in + self?.navigationController?.popViewController(animated: true) + self?.tableView.reloadData() + } + viewController.isModalInPresentation = true + navigationController?.pushViewController(viewController, animated: true) + } catch { + wpAssertionFailure("Failed to fetch pages", userInfo: ["error": "\(error)"]) // This should never happen + } + } + + @objc 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() + } +} + private enum Strings { static let errorMessage = NSLocalizedString("postSettings.updateFailedMessage", value: "Failed to update the post settings", comment: "Error message on post/page settings screen") } diff --git a/WordPress/Classes/ViewRelated/Post/PostSettingsViewController.m b/WordPress/Classes/ViewRelated/Post/PostSettingsViewController.m index 88f5aebb8961..3b25081a3f3f 100644 --- a/WordPress/Classes/ViewRelated/Post/PostSettingsViewController.m +++ b/WordPress/Classes/ViewRelated/Post/PostSettingsViewController.m @@ -42,7 +42,8 @@ typedef NS_ENUM(NSInteger, PostSettingsRow) { PostSettingsRowSlug, PostSettingsRowExcerpt, PostSettingsRowSocialNoConnections, - PostSettingsRowSocialRemainingShares + PostSettingsRowSocialRemainingShares, + PostSettingsRowParentPage }; static CGFloat CellHeight = 44.0f; @@ -466,6 +467,8 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger return 1; } else if (sec == PostSettingsSectionMoreOptions) { return 2; + } else if (sec == PostSettingsSectionPageAttributes) { + return 1; } return 0; @@ -502,6 +505,8 @@ - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInte } 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; } @@ -584,6 +589,8 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N cell = [self configureRemainingSharesCell]; } else if (sec == PostSettingsSectionMoreOptions) { cell = [self configureMoreOptionsCellForIndexPath:indexPath]; + } else if (sec == PostSettingsSectionPageAttributes) { + cell = [self configurePageAttributesCellForIndexPath:indexPath]; } return cell ?: [UITableViewCell new]; @@ -626,6 +633,8 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath [self showEditSlugController]; } else if (cell.tag == PostSettingsRowExcerpt) { [self showEditExcerptController]; + } else if (cell.tag == PostSettingsRowParentPage) { + [self showParentPageController]; } } @@ -1399,6 +1408,23 @@ - (void)reloadFeaturedImageCell { withRowAnimation:UITableViewRowAnimationFade]; } +// 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 diff --git a/WordPress/Classes/ViewRelated/Post/PostSettingsViewController_Internal.h b/WordPress/Classes/ViewRelated/Post/PostSettingsViewController_Internal.h index bccf3b37aa83..a4e6575b4eec 100644 --- a/WordPress/Classes/ViewRelated/Post/PostSettingsViewController_Internal.h +++ b/WordPress/Classes/ViewRelated/Post/PostSettingsViewController_Internal.h @@ -10,7 +10,8 @@ typedef enum { PostSettingsSectionDisabledTwitter, // NOTE: Clean up when Twitter has been removed from Publicize services. PostSettingsSectionSharesRemaining, PostSettingsSectionGeolocation, - PostSettingsSectionMoreOptions + PostSettingsSectionMoreOptions, + PostSettingsSectionPageAttributes } PostSettingsSection;