Skip to content

Commit

Permalink
Merge branch 'trunk' into fix/inability-to-dismiss-keyboard
Browse files Browse the repository at this point in the history
  • Loading branch information
guarani committed Mar 16, 2022
2 parents 2bd71b3 + 4def945 commit a16e2a1
Show file tree
Hide file tree
Showing 97 changed files with 703 additions and 285 deletions.
2 changes: 1 addition & 1 deletion Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ abstract_target 'Apps' do

pod 'Gridicons', '~> 1.1.0'

pod 'WordPressAuthenticator', '~> 1.43.1'
pod 'WordPressAuthenticator', '~> 2.0.0-beta.1'
# pod 'WordPressAuthenticator', :git => 'https://github.com/wordpress-mobile/WordPressAuthenticator-iOS.git', :branch => ''
# pod 'WordPressAuthenticator', :git => 'https://github.com/wordpress-mobile/WordPressAuthenticator-iOS.git', :commit => ''
# pod 'WordPressAuthenticator', :path => '../WordPressAuthenticator-iOS'
Expand Down
14 changes: 5 additions & 9 deletions Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ PODS:
- RNTAztecView
- JTAppleCalendar (8.0.3)
- Kanvas (1.2.8)
- lottie-ios (3.1.9)
- MediaEditor (1.2.1):
- CropViewController (~> 2.5.3)
- MRProgress (0.8.3):
Expand Down Expand Up @@ -478,12 +477,11 @@ PODS:
- WordPress-Aztec-iOS (1.19.8)
- WordPress-Editor-iOS (1.19.8):
- WordPress-Aztec-iOS (= 1.19.8)
- WordPressAuthenticator (1.43.1):
- WordPressAuthenticator (2.0.0-beta.1):
- Alamofire (~> 4.8)
- CocoaLumberjack (~> 3.5)
- GoogleSignIn (~> 6.0.1)
- Gridicons (~> 1.0)
- lottie-ios (~> 3.1.6)
- "NSURL+IDN (= 0.4)"
- SVProgressHUD (~> 2.2.5)
- WordPressKit (~> 4.18-beta)
Expand Down Expand Up @@ -592,7 +590,7 @@ DEPENDENCIES:
- Starscream (= 3.0.6)
- SVProgressHUD (= 2.2.5)
- WordPress-Editor-iOS (~> 1.19.8)
- WordPressAuthenticator (~> 1.43.1)
- WordPressAuthenticator (~> 2.0.0-beta.1)
- WordPressKit (~> 4.49.0-beta.1)
- WordPressMocks (~> 0.0.15)
- WordPressShared (~> 1.17.1)
Expand Down Expand Up @@ -627,7 +625,6 @@ SPEC REPOS:
- GTMSessionFetcher
- JTAppleCalendar
- Kanvas
- lottie-ios
- MediaEditor
- MRProgress
- Nimble
Expand Down Expand Up @@ -788,7 +785,7 @@ SPEC CHECKSUMS:
DoubleConversion: e22e0762848812a87afd67ffda3998d9ef29170c
Down: 71bf4af3c04fa093e65dffa25c4b64fa61287373
FBLazyVector: 2bf7b5e351f8e33867210ff6eb9c5c178a035522
FBReactNativeSpec: b4076f780f69b07abd859b279490f401d127c0ec
FBReactNativeSpec: 5a1f15997f42c2f266b63a6b9c3e92a9eca049f5
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
FormatterKit: 184db51bf120b633693a73624a4cede89ec51a41
FSInteractiveMap: a396f610f48b76cb540baa87139d056429abda86
Expand All @@ -801,7 +798,6 @@ SPEC CHECKSUMS:
Gutenberg: a8a0fcb4c40070f4f71f7ce50ce2fd29e83a1bc8
JTAppleCalendar: 932cadea40b1051beab10f67843451d48ba16c99
Kanvas: 9eab00cc89669b38858d42d5f30c810876b31344
lottie-ios: 3a3758ef5a008e762faec9c9d50a39842f26d124
MediaEditor: 20cdeb46bdecd040b8bc94467ac85a52b53b193a
MRProgress: 16de7cc9f347e8846797a770db102a323fe7ef09
Nimble: 7bed62ffabd6dbfe05f5925cbc43722533248990
Expand Down Expand Up @@ -856,7 +852,7 @@ SPEC CHECKSUMS:
UIDeviceIdentifier: af4e11e25a2ea670078e2bd677bb0e8144f9f063
WordPress-Aztec-iOS: 7d11d598f14c82c727c08b56bd35fbeb7dafb504
WordPress-Editor-iOS: 9eb9f12f21a5209cb837908d81ffe1e31cb27345
WordPressAuthenticator: aa53a5339e241852252e16199e23bd9c3364b983
WordPressAuthenticator: abf8310fc4ebab25a81cb96211df80b5ec1db479
WordPressKit: 158a036f5c7f1df7dc345993d8990eeb17a93906
WordPressMocks: 6b52b0764d9939408151367dd9c6e8a910877f4d
WordPressShared: 0c4bc5e25765732fcf5d07f28c81970ab28493fb
Expand All @@ -873,6 +869,6 @@ SPEC CHECKSUMS:
ZendeskSupportSDK: 3a8e508ab1d9dd22dc038df6c694466414e037ba
ZIPFoundation: ae5b4b813d216d3bf0a148773267fff14bd51d37

PODFILE CHECKSUM: cafbf4ab3cda13373d8d52183bd2fe9aa7f0ec1f
PODFILE CHECKSUM: 55b9d3eb64a93484c09355829734180f965fe931

COCOAPODS: 1.11.2
2 changes: 2 additions & 0 deletions RELEASE-NOTES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* [*] Quick Start: updated the design for the Quick Start cell on My Site [#18095]
* [*] Reader: Fixed a bug where comment replies are misplaced after its parent comment is moderated [#18094]
* [*] Bug fix: Allow keyboard to be dismissed when the password field is focused during WP.com account creation.
* [*] iPad: Fixed a bug where the current displayed section wasn't selected on the menu [#18118]

19.4
-----
Expand All @@ -15,6 +16,7 @@
* [*] Weekly Roundup: We made some further changes to try and ensure that Weekly Roundup notifications are showing up for everybody who's enabled them [#18029]
* [*] Block editor: Autocorrected Headings no longer apply bold formatting if they weren't already bold. [#17844]
* [***] Block editor: Support for multiple color palettes [https://github.com/wordpress-mobile/gutenberg-mobile/pull/4588]
* [**] User profiles: Fixed issue where the app wasn't displaying any of the device photos which the user had granted the app access to.

19.3
-----
Expand Down
8 changes: 8 additions & 0 deletions WordPress/Classes/Models/Blog+MySite.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import Foundation

extension Blog {
/// If the blog should show the "Jetpack" or the "General" section
@objc var shouldShowJetpackSection: Bool {
(supports(.activity) && !isWPForTeams()) || supports(.jetpackSettings)
}
}
11 changes: 7 additions & 4 deletions WordPress/Classes/Services/CommentService+Replies.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,13 @@ extension CommentService {
return
}

// also fill in the `author` parameter, so the remote only returns comments authored by the current user.
remote.getCommentsV2(for: siteID, parameters: [.parent: parentID, .author: userID]) { remoteComments in
// return the most recent commentID (if any).
success(remoteComments.sorted { $0.date > $1.date }.first?.commentID ?? 0)
// If the current user does not have permission to the site, the `author` endpoint parameter is not permitted.
// Therefore, fetch all replies and filter for the current user here.
remote.getCommentsV2(for: siteID, parameters: [.parent: parentID]) { remoteComments in
// Filter for comments authored by the current user, and return the most recent commentID (if any).
success(remoteComments
.filter { $0.authorID == userID }
.sorted { $0.date > $1.date }.first?.commentID ?? 0)
} failure: { error in
failure(error)
}
Expand Down
8 changes: 8 additions & 0 deletions WordPress/Classes/Services/CommentService.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,13 @@ extern NSUInteger const WPTopLevelHierarchicalCommentsPerPage;
// Restore draft reply
- (Comment *)restoreReplyForComment:(Comment *)comment;

// Find cached comments
- (NSSet *)findCommentsWithPostID:(NSNumber *)postID inBlog:(Blog *)blog;

- (Comment *)findCommentWithID:(NSNumber *)commentID inBlog:(Blog *)blog;

- (Comment *)findCommentWithID:(NSNumber *)commentID fromPost:(ReaderPost *)post;

// Sync comments
- (void)syncCommentsForBlog:(Blog *)blog
success:(void (^)(BOOL hasMore))success
Expand Down Expand Up @@ -71,6 +74,11 @@ extern NSUInteger const WPTopLevelHierarchicalCommentsPerPage;
success:(void (^_Nullable)(Comment *_Nullable))success
failure:(void (^_Nullable)(NSError *_Nullable))failure;

- (void)loadCommentWithID:(NSNumber *_Nonnull)commentID
forPost:(ReaderPost *_Nonnull)post
success:(void (^_Nullable)(Comment *_Nullable))success
failure:(void (^_Nullable)(NSError *_Nullable))failure;

// Upload comment
- (void)uploadComment:(Comment *)comment
success:(void (^)(void))success
Expand Down
46 changes: 46 additions & 0 deletions WordPress/Classes/Services/CommentService.m
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,52 @@ - (void)loadCommentWithID:(NSNumber *)commentID
}];
}

- (void)loadCommentWithID:(NSNumber *)commentID
forPost:(ReaderPost *)post
success:(void (^)(Comment *comment))success
failure:(void (^)(NSError *))failure {

NSManagedObjectID *postID = post.objectID;
CommentServiceRemoteREST *service = [self restRemoteForSite:post.siteID];

[service getCommentWithID:commentID
success:^(RemoteComment *remoteComment) {
[self.managedObjectContext performBlock:^{
ReaderPost *post = (ReaderPost *)[self.managedObjectContext existingObjectWithID:postID error:nil];
if (!post) {
return;
}

Comment *comment = [self findCommentWithID:remoteComment.commentID fromPost:post];

if (!comment) {
comment = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([Comment class]) inManagedObjectContext:self.managedObjectContext];
comment.dateCreated = [NSDate new];
}

comment.post = post;
[self updateComment:comment withRemoteComment:remoteComment];

[[ContextManager sharedInstance] saveContext:self.managedObjectContext withCompletionBlock:^{
if (success) {
dispatch_async(dispatch_get_main_queue(), ^{
success(comment);
});
}
}];
}];
} failure:^(NSError *error) {
DDLogError(@"Error loading comment for post: %@", error);
[self.managedObjectContext performBlock:^{
if (failure) {
dispatch_async(dispatch_get_main_queue(), ^{
failure(error);
});
}
}];
}];
}

// Upload comment
- (void)uploadComment:(Comment *)comment
success:(void (^)(void))success
Expand Down
10 changes: 10 additions & 0 deletions WordPress/Classes/Services/ReaderPostService.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,4 +237,14 @@ extern NSString * const ReaderPostServiceToggleSiteFollowingState;
deletingEarlier:(BOOL)deleteEarlier
callingSuccess:(void (^)(NSInteger count, BOOL hasMore))success;


/**
Get a cached site's ReaderPost with the specified ID.
@param postID ID of the post.
@param siteID ID of th site the post belongs to.
@return the matching ReaderPost.
*/
- (ReaderPost *)findPostWithID:(NSNumber *)postID forSite:(NSNumber *)siteID;

@end
15 changes: 15 additions & 0 deletions WordPress/Classes/Services/ReaderPostService.m
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ - (void)fetchPost:(NSUInteger)postID forSite:(NSUInteger)siteID isFeed:(BOOL)isF

} failure:^(NSError *error) {
if (failure) {
DDLogError(@"Error fetching post with id %@ and site %@. %@", postID, siteID, error);
failure(error);
}
}];
Expand Down Expand Up @@ -187,6 +188,7 @@ - (void)fetchPostAtURL:(NSURL *)postURL

} failure:^(NSError *error) {
if (failure) {
DDLogError(@"Error fetching post with url %@. %@", postURL, error);
failure(error);
}
}];
Expand All @@ -206,6 +208,19 @@ - (void)refreshPostsForFollowedTopic
}];
}

- (ReaderPost *)findPostWithID:(NSNumber *)postID forSite:(NSNumber *)siteID
{
NSError *error;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:NSStringFromClass([ReaderPost class])];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"postID = %@ AND siteID = %@", postID, siteID];
NSArray *results = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (error) {
DDLogError(@"Error loading cached post with id %@ and site %@. %@", postID, siteID, error);
return nil;
}

return results.firstObject;
}

#pragma mark - Update Methods

Expand Down
10 changes: 10 additions & 0 deletions WordPress/Classes/Stores/StatsInsightsStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -463,18 +463,28 @@ private extension StatsInsightsStore {

transaction { state in
state.lastPostInsight = StatsRecord.insight(for: blog, type: .lastPostInsight).flatMap { StatsLastPostInsight(statsRecordValues: $0.recordValues) }
state.lastPostSummaryStatus = state.lastPostInsight == nil ? .error : .success
state.allTimeStats = StatsRecord.insight(for: blog, type: .allTimeStatsInsight).flatMap { StatsAllTimesInsight(statsRecordValues: $0.recordValues) }
state.allTimeStatus = state.allTimeStats == nil ? .error : .success
state.annualAndMostPopularTime = StatsRecord.insight(for: blog, type: .annualAndMostPopularTimes).flatMap { StatsAnnualAndMostPopularTimeInsight(statsRecordValues: $0.recordValues) }
state.annualAndMostPopularTimeStatus = state.annualAndMostPopularTime != nil ? .error : .success
state.publicizeFollowers = StatsRecord.insight(for: blog, type: .publicizeConnection).flatMap { StatsPublicizeInsight(statsRecordValues: $0.recordValues) }
state.publicizeFollowersStatus = state.publicizeFollowers == nil ? .error : .success
state.todaysStats = StatsRecord.insight(for: blog, type: .today).flatMap { StatsTodayInsight(statsRecordValues: $0.recordValues) }
state.todaysStatsStatus = state.todaysStats == nil ? .error : .success
state.postingActivity = StatsRecord.insight(for: blog, type: .streakInsight).flatMap { StatsPostingStreakInsight(statsRecordValues: $0.recordValues) }
state.postingActivityStatus = state.postingActivity == nil ? .error : .success
state.topTagsAndCategories = StatsRecord.insight(for: blog, type: .tagsAndCategories).flatMap { StatsTagsAndCategoriesInsight(statsRecordValues: $0.recordValues) }
state.tagsAndCategoriesStatus = state.topTagsAndCategories == nil ? .error : .success
state.topCommentsInsight = StatsRecord.insight(for: blog, type: .commentInsight).flatMap { StatsCommentsInsight(statsRecordValues: $0.recordValues) }
state.commentsInsightStatus = state.topCommentsInsight == nil ? .error : .success

let followersInsight = StatsRecord.insight(for: blog, type: .followers)

state.dotComFollowers = followersInsight.flatMap { StatsDotComFollowersInsight(statsRecordValues: $0.recordValues) }
state.dotComFollowersStatus = state.dotComFollowers == nil ? .error : .success
state.emailFollowers = followersInsight.flatMap { StatsEmailFollowersInsight(statsRecordValues: $0.recordValues) }
state.emailFollowersStatus = state.emailFollowers == nil ? .error : .success
}

DDLogInfo("Insights load from cache")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ class DashboardStatsCardCell: UICollectionViewCell, Reusable {

// MARK: Private Variables

private var viewModel: DashboardStatsViewModel?

private lazy var stackView: UIStackView = {
let stackView = UIStackView()
stackView.axis = .vertical
Expand All @@ -29,11 +31,11 @@ class DashboardStatsCardCell: UICollectionViewCell, Reusable {

extension DashboardStatsCardCell: BlogDashboardCardConfigurable {
func configure(blog: Blog, viewController: BlogDashboardViewController?, apiResponse: BlogDashboardRemoteEntity?) {
guard let viewController = viewController else {
guard let viewController = viewController, let apiResponse = apiResponse else {
return
}

// TODO: Use apiResponse to create a View Model and use it to populate the cell
self.viewModel = DashboardStatsViewModel(apiResponse: apiResponse)

clearFrames()
addTodayStatsCard(for: blog, in: viewController)
Expand Down Expand Up @@ -69,11 +71,10 @@ extension DashboardStatsCardCell: BlogDashboardCardConfigurable {
return stackview
}

// TODO: Data is now static. It should be brought in from the view model.
private func statsViews() -> [UIView] {
let viewsStatsView = DashboardSingleStatView(countString: "1,492", title: Strings.viewsTitle)
let visitorsStatsView = DashboardSingleStatView(countString: "885", title: Strings.visitorsTitle)
let likesStatsView = DashboardSingleStatView(countString: "112", title: Strings.likesTitle)
let viewsStatsView = DashboardSingleStatView(countString: viewModel?.todaysViews ?? "0", title: Strings.viewsTitle)
let visitorsStatsView = DashboardSingleStatView(countString: viewModel?.todaysVisitors ?? "0", title: Strings.visitorsTitle)
let likesStatsView = DashboardSingleStatView(countString: viewModel?.todaysLikes ?? "0", title: Strings.likesTitle)
return [viewsStatsView, visitorsStatsView, likesStatsView]
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import Foundation

class DashboardStatsViewModel {

// MARK: Private Variables

private var apiResponse: BlogDashboardRemoteEntity

// MARK: Initializer

init(apiResponse: BlogDashboardRemoteEntity) {
self.apiResponse = apiResponse
}

// MARK: Public Variables

var todaysViews: String {
apiResponse.todaysStats?.views?.abbreviatedString(forHeroNumber: true) ?? "0"
}

var todaysVisitors: String {
apiResponse.todaysStats?.visitors?.abbreviatedString(forHeroNumber: true) ?? "0"
}

var todaysLikes: String {
apiResponse.todaysStats?.likes?.abbreviatedString(forHeroNumber: true) ?? "0"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,27 @@ extension Array where Element: BlogDetailsSection {
}

extension BlogDetailsSubsection {
fileprivate var sectionCategory: BlogDetailsSectionCategory {
func sectionCategory(for blog: Blog) -> BlogDetailsSectionCategory {
switch self {
case .domainCredit:
return .domainCredit
case .quickStart:
return .quickStart
case .stats, .activity:
case .activity, .jetpackSettings:
return .jetpack
case .stats where blog.shouldShowJetpackSection:
return .jetpack
case .stats where !blog.shouldShowJetpackSection:
return .general
case .pages, .posts, .media, .comments:
return .publish
case .themes, .customize:
return .personalize
case .sharing, .people, .plugins:
return .configure
case .jetpackSettings:
return .jetpack
case .home:
return .home
@unknown default:
default:
fatalError()
}
}
Expand All @@ -34,7 +36,7 @@ extension BlogDetailsViewController {
return sections.findSectionIndex(of: category) ?? NSNotFound
}

@objc func sectionCategory(subsection: BlogDetailsSubsection) -> BlogDetailsSectionCategory {
return subsection.sectionCategory
@objc func sectionCategory(subsection: BlogDetailsSubsection, blog: Blog) -> BlogDetailsSectionCategory {
return subsection.sectionCategory(for: blog)
}
}
Loading

0 comments on commit a16e2a1

Please sign in to comment.