Skip to content

Commit

Permalink
Use PostRepository to fetch pages in the Menu screen
Browse files Browse the repository at this point in the history
Fixes #21947
  • Loading branch information
crazytonyli committed Nov 2, 2023
1 parent c2493d9 commit fb3fad8
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 61 deletions.
10 changes: 3 additions & 7 deletions WordPress/Classes/Services/MenusService.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,12 @@ typedef void(^MenusServiceFailureBlock)(NSError *error);
failure:(nullable MenusServiceFailureBlock)failure;

/**
* @brief Generate a list MenuItems from the blog's top-level pages.
* @brief Create a list MenuItems from the given page.
*
* @param blog The blog to use for pages. Cannot be nil.
* @param success The success handler. Can be nil.
* @param failure The failure handler. Can be nil.
* @return A MenuItem instance for the page if it's a top-level page. Otherwise, nil.
*
*/
- (void)generateDefaultMenuItemsForBlog:(Blog *)blog
success:(nullable void(^)(NSArray <MenuItem *> * _Nullable defaultItems))success
failure:(nullable MenusServiceFailureBlock)failure;
- (nullable MenuItem *)createItemWithPageID:(NSManagedObjectID *)pageObjectID inContext:(NSManagedObjectContext *)context;

@end

Expand Down
60 changes: 15 additions & 45 deletions WordPress/Classes/Services/MenusService.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
#import "WordPress-Swift.h"
@import WordPressKit;

NS_ASSUME_NONNULL_BEGIN

@implementation MenusService

#pragma mark - Menus availability
Expand Down Expand Up @@ -161,47 +159,21 @@ - (void)deleteMenu:(Menu *)menu
failure:failure];
}

- (void)generateDefaultMenuItemsForBlog:(Blog *)blog
success:(nullable void(^)(NSArray <MenuItem *> * _Nullable defaultItems))success
failure:(nullable MenusServiceFailureBlock)failure
{
// Get the latest list of Pages available to the site.
PostServiceSyncOptions *options = [[PostServiceSyncOptions alloc] init];
options.statuses = @[PostStatusPublish];
options.order = PostServiceResultsOrderAscending;
options.orderBy = PostServiceResultsOrderingByTitle;
PostService *postService = [[PostService alloc] initWithManagedObjectContext:self.managedObjectContext];
[postService syncPostsOfType:PostServiceTypePage
withOptions:options
forBlog:blog
success:^(NSArray *pages) {
[self.managedObjectContext performBlock:^{

if (!pages.count) {
success(nil);
return;
}
NSMutableArray *items = [NSMutableArray arrayWithCapacity:pages.count];
// Create menu items for the top parent pages.
for (Page *page in pages) {
if ([page.parentID integerValue] > 0) {
continue;
}
MenuItem *pageItem = [NSEntityDescription insertNewObjectForEntityForName:[MenuItem entityName] inManagedObjectContext:self.managedObjectContext];
pageItem.contentID = page.postID;
pageItem.name = page.titleForDisplay;
pageItem.type = MenuItemTypePage;
[items addObject:pageItem];
}

[[ContextManager sharedInstance] saveContext:self.managedObjectContext withCompletionBlock:^{
if (success) {
success(items);
}
} onQueue:dispatch_get_main_queue()];
}];
}
failure:failure];
- (MenuItem *)createItemWithPageID:(NSManagedObjectID *)pageObjectID inContext:(NSManagedObjectContext *)context {
Page *page = [context existingObjectWithID:pageObjectID error:nil];
if (page == nil) {
return nil;
}

if ([page.parentID integerValue] > 0) {
return nil;
}

MenuItem *pageItem = [NSEntityDescription insertNewObjectForEntityForName:[MenuItem entityName] inManagedObjectContext:self.managedObjectContext];
pageItem.contentID = page.postID;
pageItem.name = page.titleForDisplay;
pageItem.type = MenuItemTypePage;
return pageItem;
}

#pragma mark - private
Expand Down Expand Up @@ -435,5 +407,3 @@ - (RemoteMenuItem *)remoteItemFromItem:(MenuItem *)item withItems:(NSOrderedSet<
}

@end

NS_ASSUME_NONNULL_END
32 changes: 32 additions & 0 deletions WordPress/Classes/Services/PostRepository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,38 @@ extension PostRepository {
)
}

/// Fetch all pages of the given site.
///
/// - Parameters:
/// - statuses: Only fetch pages whose status is included in the given statues.
/// - blogID: Object ID of the site.
/// - Returns: A `Task` instance representing the fetching. The fetch pages API requests will stop if the task is cancelled.
func fetchAllPages(statuses: [BasePost.Status], in blogID: TaggedManagedObjectID<Blog>) -> Task<[TaggedManagedObjectID<Page>], Swift.Error> {
Task {
let pageSize = 100
var allPages = [TaggedManagedObjectID<Page>]()
while true {
try Task.checkCancellation()

let pageRange = allPages.count..<(allPages.count + pageSize)
let current = try await fetch(
type: Page.self,
statuses: statuses,
authorUserID: nil,
range: pageRange,
deleteOtherLocalPosts: false,
in: blogID
)
allPages.append(contentsOf: current)

if current.isEmpty || current.count < pageSize {
break
}
}
return allPages
}
}

private func fetch<P: AbstractPost>(
type: P.Type,
searchInput: String? = nil,
Expand Down
1 change: 1 addition & 0 deletions WordPress/Classes/System/WordPress-Bridging-Header.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#import "MeHeaderView.h"
#import "MenuItem.h"
#import "MenuItemsViewController.h"
#import "MenusService.h"
#import "MenusViewController.h"

#import "NSObject+Helpers.h"
Expand Down
5 changes: 4 additions & 1 deletion WordPress/Classes/ViewRelated/Menus/MenusViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@

NS_ASSUME_NONNULL_BEGIN

@class Blog;
@class Blog, MenusService;

@interface MenusViewController : UIViewController

+ (MenusViewController *)controllerWithBlog:(Blog *)blog;

@property (nonatomic, strong, readonly) Blog *blog;
@property (nonatomic, strong, readonly) MenusService *menusService;

@end

NS_ASSUME_NONNULL_END
20 changes: 12 additions & 8 deletions WordPress/Classes/ViewRelated/Menus/MenusViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
#import <WordPressShared/WPFontManager.h>
#import <WordPressShared/WPStyleGuide.h>



static CGFloat const ScrollViewOffsetAdjustmentPadding = 10.0;

@interface MenusViewController () <UIScrollViewDelegate, MenuHeaderViewControllerDelegate, MenuDetailsViewControllerDelegate, MenuItemsViewControllerDelegate>
Expand All @@ -32,9 +30,6 @@ @interface MenusViewController () <UIScrollViewDelegate, MenuHeaderViewControlle
@property (nonatomic, strong, readonly) UILabel *itemsLoadingLabel;
@property (nonatomic, strong, readonly) UIBarButtonItem *saveButtonItem;

@property (nonatomic, strong, readonly) Blog *blog;
@property (nonatomic, strong, readonly) MenusService *menusService;

@property (nonatomic, strong) MenuLocation *selectedMenuLocation;
@property (nonatomic, strong) Menu *updatedMenuForSaving;
@property (nonatomic, strong) Menu *initialMenuSelection;
Expand All @@ -45,6 +40,8 @@ @interface MenusViewController () <UIScrollViewDelegate, MenuHeaderViewControlle
@property (nonatomic, assign) BOOL needsSave;
@property (nonatomic, assign) BOOL isSaving;

@property (nonatomic, strong) void (^fetchAllPagesCancellationHandler)(void);

@end

@implementation MenusViewController
Expand Down Expand Up @@ -176,6 +173,15 @@ - (void)viewWillDisappear:(BOOL)animated
[[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];

if (self.navigationController == nil && self.fetchAllPagesCancellationHandler != nil) {
self.fetchAllPagesCancellationHandler();
}
}

#pragma mark - Views setup

- (void)updateScrollViewContentSize
Expand Down Expand Up @@ -355,9 +361,7 @@ - (void)loadDefaultMenuItemsIfNeeded
void(^failureBlock)(NSError *) = ^(NSError * __unused error) {
weakSelf.itemsLoadingLabel.text = NSLocalizedString(@"An error occurred loading the menu, please check your internet connection.", @"Menus error message seen when an error occurred loading a specific menu.");
};
[self.menusService generateDefaultMenuItemsForBlog:self.blog
success:successBlock
failure:failureBlock];
self.fetchAllPagesCancellationHandler = [self fetchAllPagesWithSuccess:successBlock failure:failureBlock];
}
}

Expand Down
36 changes: 36 additions & 0 deletions WordPress/Classes/ViewRelated/Menus/MenusViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import Foundation

extension MenusViewController {

/// Fetch all pages from the site.
///
/// - Returns: A block that can be used to cancel the fetching.
@objc func fetchAllPages(success: @escaping ([MenuItem]) -> Void, failure: @escaping (Error) -> Void) -> () -> Void {
let coreDataStack = ContextManager.shared
let repository = PostRepository(coreDataStack: coreDataStack)
let fetchAllPagesTask = repository.fetchAllPages(statuses: [.publish], in: TaggedManagedObjectID(blog))

// Wait for the fetching all pages task to complete and pass its result to the success or failure block.
Task { [weak self] in
let allPages: [TaggedManagedObjectID<Page>]
do {
allPages = try await fetchAllPagesTask.value
} catch {
failure(error)
return
}

guard let menusService = self?.menusService else { return }

await menusService.managedObjectContext.perform {
let items = allPages.compactMap {
menusService.createItem(withPageID: $0.objectID, in: menusService.managedObjectContext)
}
success(items)
}
}

return fetchAllPagesTask.cancel
}

}
6 changes: 6 additions & 0 deletions WordPress/WordPress.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1270,6 +1270,8 @@
4A358DEA29B5F14C00BFCEBE /* SharingButton+Lookup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A358DE829B5F14C00BFCEBE /* SharingButton+Lookup.swift */; };
4A526BDF296BE9A50007B5BA /* CoreDataService.m in Sources */ = {isa = PBXBuildFile; fileRef = 4A526BDD296BE9A50007B5BA /* CoreDataService.m */; };
4A526BE0296BE9A50007B5BA /* CoreDataService.m in Sources */ = {isa = PBXBuildFile; fileRef = 4A526BDD296BE9A50007B5BA /* CoreDataService.m */; };
4A535E142AF3368B008B87B9 /* MenusViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A535E132AF3368B008B87B9 /* MenusViewController.swift */; };
4A535E152AF3368B008B87B9 /* MenusViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A535E132AF3368B008B87B9 /* MenusViewController.swift */; };
4A76A4BB29D4381100AABF4B /* CommentService+LikesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A76A4BA29D4381000AABF4B /* CommentService+LikesTests.swift */; };
4A76A4BD29D43BFD00AABF4B /* CommentService+MorderationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A76A4BC29D43BFD00AABF4B /* CommentService+MorderationTests.swift */; };
4A76A4BF29D4F0A500AABF4B /* reader-post-comments-success.json in Resources */ = {isa = PBXBuildFile; fileRef = 4A76A4BE29D4F0A500AABF4B /* reader-post-comments-success.json */; };
Expand Down Expand Up @@ -6895,6 +6897,7 @@
4A358DE829B5F14C00BFCEBE /* SharingButton+Lookup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SharingButton+Lookup.swift"; sourceTree = "<group>"; };
4A526BDD296BE9A50007B5BA /* CoreDataService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CoreDataService.m; sourceTree = "<group>"; };
4A526BDE296BE9A50007B5BA /* CoreDataService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CoreDataService.h; sourceTree = "<group>"; };
4A535E132AF3368B008B87B9 /* MenusViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenusViewController.swift; sourceTree = "<group>"; };
4A76A4BA29D4381000AABF4B /* CommentService+LikesTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CommentService+LikesTests.swift"; sourceTree = "<group>"; };
4A76A4BC29D43BFD00AABF4B /* CommentService+MorderationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CommentService+MorderationTests.swift"; sourceTree = "<group>"; };
4A76A4BE29D4F0A500AABF4B /* reader-post-comments-success.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "reader-post-comments-success.json"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -10046,6 +10049,7 @@
children = (
086E1FDE1BBB35D2002D86CA /* MenusViewController.h */,
086E1FDF1BBB35D2002D86CA /* MenusViewController.m */,
4A535E132AF3368B008B87B9 /* MenusViewController.swift */,
C3B554502965C32A00A04753 /* MenusViewController+JetpackBannerViewController.swift */,
08216FA81CDBF95100304BA7 /* MenuItemEditingViewController.h */,
08216FA91CDBF95100304BA7 /* MenuItemEditingViewController.m */,
Expand Down Expand Up @@ -22147,6 +22151,7 @@
F1DB8D292288C14400906E2F /* Uploader.swift in Sources */,
FA3A281B2A39C8FF00206D74 /* BlazeCampaignSingleStatView.swift in Sources */,
3FB1929026C6109F000F5AA3 /* TimeSelectionView.swift in Sources */,
4A535E142AF3368B008B87B9 /* MenusViewController.swift in Sources */,
FAB8AB8B25AFFE7500F9F8A0 /* JetpackRestoreService.swift in Sources */,
821738091FE04A9E00BEC94C /* DateAndTimeFormatSettingsViewController.swift in Sources */,
5D6C4B081B603E03005E3C43 /* WPContentSyncHelper.swift in Sources */,
Expand Down Expand Up @@ -23802,6 +23807,7 @@
FABB20CD2602FC2C00C8785C /* PostUploadOperation.swift in Sources */,
FABB20CE2602FC2C00C8785C /* VerticallyStackedButton.m in Sources */,
FABB20CF2602FC2C00C8785C /* PageListViewController.swift in Sources */,
4A535E152AF3368B008B87B9 /* MenusViewController.swift in Sources */,
FABB20D02602FC2C00C8785C /* CoreDataHelper.swift in Sources */,
FABB20D12602FC2C00C8785C /* LocalCoreDataService.m in Sources */,
FE29EFCE29A91160007CE034 /* WPAdminConvertibleRouter.swift in Sources */,
Expand Down

0 comments on commit fb3fad8

Please sign in to comment.