Skip to content

Commit 3329b59

Browse files
authored
Implement a new CommentServiceRemote that uses .org REST API (#24555)
* Update wordpress-rs * Move getting avatar URL function * Prevent creating WordPressSite instances for WP.com sites * Implement a new `CommentServiceRemote` that uses .org REST API * Fix a compiling issue in the Keystone target
1 parent 980a463 commit 3329b59

File tree

9 files changed

+381
-16
lines changed

9 files changed

+381
-16
lines changed

Modules/Package.resolved

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Modules/Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ let package = Package(
5454
),
5555
.package(url: "https://github.com/zendesk/support_sdk_ios", from: "8.0.3"),
5656
// We can't use wordpress-rs branches nor commits here. Only tags work.
57-
.package(url: "https://github.com/Automattic/wordpress-rs", revision: "alpha-20250513"),
57+
.package(url: "https://github.com/Automattic/wordpress-rs", revision: "alpha-20250520"),
5858
.package(url: "https://github.com/wordpress-mobile/GutenbergKit", revision: "fdfe788530bbff864ce7147b5a68608d7025e078"),
5959
.package(
6060
url: "https://github.com/Automattic/color-studio",
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import Foundation
2+
import WordPressAPI
3+
import WordPressAPIInternal
4+
5+
extension Dictionary where Key == UserAvatarSize, Value == WpResponseString {
6+
7+
public func avatarURL() -> URL? {
8+
guard let url = self[.size96] ?? self[.size48] ?? self[.size24], let url else {
9+
return nil
10+
}
11+
12+
return URL(string: url)
13+
}
14+
15+
}

Modules/Sources/WordPressCore/Users/UserService.swift

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -86,19 +86,11 @@ private extension DisplayUser {
8686
firstName: user.firstName,
8787
lastName: user.lastName,
8888
displayName: user.name,
89-
profilePhotoUrl: Self.profilePhotoUrl(for: user),
89+
profilePhotoUrl: user.avatarUrls?.avatarURL(),
9090
role: role,
9191
emailAddress: user.email,
9292
websiteUrl: user.link,
9393
biography: user.description
9494
)
9595
}
96-
97-
static func profilePhotoUrl(for user: UserWithEditContext) -> URL? {
98-
guard let url = user.avatarUrls?[.size96] ?? user.avatarUrls?[.size48] ?? user.avatarUrls?[.size24], let url else {
99-
return nil
100-
}
101-
102-
return URL(string: url)
103-
}
10496
}

Sources/WordPressData/Swift/Blog+SelfHosted.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,9 @@ public enum WordPressSite {
183183
case selfHosted(blogId: TaggedManagedObjectID<Blog>, apiRootURL: ParsedUrl, username: String, authToken: String)
184184

185185
public init(blog: Blog) throws {
186-
if let account = blog.account {
187-
let authToken = try account.authToken ?? WPAccount.token(forUsername: account.username)
188-
self = .dotCom(siteId: blog.dotComID?.intValue ?? 0, authToken: authToken)
186+
if let _ = blog.account {
187+
// WP.com support is not ready yet.
188+
throw NSError(domain: "WordPressAPI", code: 0)
189189
} else {
190190
let url = try blog.restApiRootURL ?? blog.getUrl().appending(path: "wp-json").absoluteString
191191
let apiRootURL = try ParsedUrl.parse(input: url)

WordPress/Classes/Services/CommentService+Swift.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import Foundation
2+
import WordPressData
3+
14
/// Encapsulates actions related to fetching reply comments.
25
///
36
extension CommentService {
@@ -74,6 +77,32 @@ extension CommentService {
7477
self.coreDataStack.save(context, completion: completion, on: .main)
7578
}
7679
}
80+
81+
// The app may display `RemoteComment.postTitle` on comments list. However, the comments endpoint in the .org
82+
// REST API does not return post title. This function prefetchs the associated posts and saves them locally if
83+
// they don't already exist.
84+
@objc(fetchPostsIfNeededForComments:inBlog:)
85+
public func fetchPostsIfNeeded(for comments: [RemoteComment], in blog: Blog) {
86+
// Find posts that do not exists locally.
87+
let postIds = comments
88+
.reduce(into: Set<NSNumber>()) { result, comment in
89+
if let postId = comment.postID, comment.postTitle == nil {
90+
result.insert(postId)
91+
}
92+
}
93+
.filter { postId in
94+
blog.lookupPost(withID: postId, in: blog.managedObjectContext!) == nil
95+
}
96+
97+
let blogId = TaggedManagedObjectID(blog)
98+
DDLogInfo("Pre-fetching \(postIds.count) posts...")
99+
Task {
100+
let repository = PostRepository()
101+
for postId in postIds {
102+
_ = try? await repository.getPost(withID: postId, from: blogId)
103+
}
104+
}
105+
}
77106
}
78107

79108
private extension CommentService {

WordPress/Classes/Services/CommentService.m

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,8 @@ - (void)syncCommentsForBlog:(Blog *)blog
175175
fetchedComments = [self filterUnrepliedComments:comments forAuthor:author];
176176
}
177177
[self mergeComments:fetchedComments forBlog:blog purgeExisting:YES];
178+
[self fetchPostsIfNeededForComments:fetchedComments inBlog:blog];
179+
178180
blog.lastCommentsSync = [NSDate date];
179181
} completion:^{
180182
[[self class] stopSyncingCommentsForBlog:blogID];

0 commit comments

Comments
 (0)