Skip to content

Commit 47f97e7

Browse files
committed
Merge branch 'trunk' into feature/17790-show_cached_comment
2 parents 94c981a + ed33989 commit 47f97e7

File tree

9 files changed

+149
-11
lines changed

9 files changed

+149
-11
lines changed

.buildkite/pipeline.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ steps:
4949
#################
5050
# Run Unit Tests
5151
#################
52-
- label: "🧪 Unit Tests"
52+
- label: "🔬 Unit Tests"
5353
command: ".buildkite/commands/run-unit-tests.sh"
5454
depends_on: "build"
5555
env: *common_env
@@ -75,7 +75,7 @@ steps:
7575
#################
7676
# UI Tests
7777
#################
78-
- label: "🧪 UI Tests (iPhone)"
78+
- label: "🔬 UI Tests (iPhone)"
7979
command: .buildkite/commands/run-ui-tests.sh WordPressUITests 'iPhone 13' 15.0
8080
depends_on: "build"
8181
env: *common_env
@@ -86,7 +86,7 @@ steps:
8686
- github_commit_status:
8787
context: "UI Tests (iPhone)"
8888

89-
- label: "🧪 UI Tests (iPad)"
89+
- label: "🔬 UI Tests (iPad)"
9090
command: .buildkite/commands/run-ui-tests.sh WordPressUITests "iPad Air (4th generation)" 15.0
9191
depends_on: "build"
9292
env: *common_env

RELEASE-NOTES.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
-----
33
* [**] Some of the screens of the app has a new, fresh and more modern visual, including the initial one: My Site. [#17812]
44
* [**] Notifications: added a button to mark all notifications in the selected filter as read. [#17840]
5+
* [*] Stats: fix navigation between Stats tab. [#17856]
6+
* [*] Quick Start: Fixed a bug where a user logging in via a self-hosted site not connected to Jetpack would see Quick Start when selecting "No thanks" on the Quick Start prompt. [#17855]
57

68
19.1
79
-----
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import UIKit
2+
3+
protocol DashboardCardInnerErrorViewDelegate: AnyObject {
4+
func retry()
5+
}
6+
7+
class DashboardCardInnerErrorView: UIStackView {
8+
weak var delegate: DashboardCardInnerErrorViewDelegate?
9+
10+
private lazy var errorTitle: UILabel = {
11+
let errorTitle = UILabel()
12+
errorTitle.textAlignment = .center
13+
errorTitle.textColor = .textSubtle
14+
WPStyleGuide.configureLabel(errorTitle, textStyle: .callout, fontWeight: .semibold)
15+
return errorTitle
16+
}()
17+
18+
private lazy var retryLabel: UILabel = {
19+
let retryLabel = UILabel()
20+
retryLabel.textAlignment = .center
21+
retryLabel.text = Strings.tapToRetry
22+
retryLabel.textColor = .textSubtle
23+
WPStyleGuide.configureLabel(retryLabel, textStyle: .callout, fontWeight: .regular)
24+
return retryLabel
25+
}()
26+
27+
convenience init(message: String, canRetry: Bool) {
28+
self.init(arrangedSubviews: [])
29+
30+
errorTitle.text = message
31+
addArrangedSubview(errorTitle)
32+
33+
axis = .vertical
34+
spacing = Constants.spacing
35+
36+
if canRetry {
37+
addArrangedSubview(retryLabel)
38+
39+
isUserInteractionEnabled = true
40+
let tap = UITapGestureRecognizer(target: self, action: #selector(didTap))
41+
addGestureRecognizer(tap)
42+
}
43+
}
44+
45+
@objc func didTap() {
46+
delegate?.retry()
47+
}
48+
49+
private enum Constants {
50+
static let spacing: CGFloat = 8
51+
}
52+
53+
private enum Strings {
54+
static let tapToRetry = NSLocalizedString("Tap to retry", comment: "Label for a button to retry loading posts")
55+
}
56+
}

WordPress/Classes/ViewRelated/Blog/Blog Dashboard/Cards/Posts/PostsCardViewController.swift

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import UIKit
1111

1212
private var viewModel: PostsCardViewModel!
1313
private var ghostableTableView: UITableView?
14+
private var errorView: DashboardCardInnerErrorView?
1415

1516
private let status: BasePost.Status = .draft
1617

@@ -31,6 +32,11 @@ import UIKit
3132
viewModel.viewDidLoad()
3233
}
3334

35+
override func viewWillAppear(_ animated: Bool) {
36+
super.viewWillAppear(animated)
37+
hideSeparatorForGhostCells()
38+
}
39+
3440
override func viewDidAppear(_ animated: Bool) {
3541
super.viewDidAppear(animated)
3642
tableView.dataSource = viewModel
@@ -49,14 +55,15 @@ private extension PostsCardViewController {
4955
func configureTableView() {
5056
view.addSubview(tableView)
5157
tableView.translatesAutoresizingMaskIntoConstraints = false
58+
tableView.isScrollEnabled = false
5259
view.pinSubviewToAllEdges(tableView)
5360
let postCompactCellNib = PostCompactCell.defaultNib
5461
tableView.register(postCompactCellNib, forCellReuseIdentifier: PostCompactCell.defaultReuseID)
5562
tableView.separatorStyle = .none
5663
}
5764

5865
func configureGhostableTableView() {
59-
let ghostableTableView = IntrinsicTableView()
66+
let ghostableTableView = PostCardTableView()
6067

6168
view.addSubview(ghostableTableView)
6269

@@ -83,6 +90,11 @@ private extension PostsCardViewController {
8390
ghostableTableView?.removeFromSuperview()
8491
}
8592

93+
func hideSeparatorForGhostCells() {
94+
ghostableTableView?.visibleCells
95+
.forEach { ($0 as? PostCompactCell)?.hideSeparator() }
96+
}
97+
8698
enum Constants {
8799
static let numberOfPosts = 3
88100
}
@@ -105,8 +117,21 @@ extension PostsCardViewController: PostsCardView {
105117
}
106118

107119
func hideLoading() {
120+
errorView?.removeFromSuperview()
108121
removeGhostableTableView()
109122
}
123+
124+
func showError(message: String, retry: Bool) {
125+
let errorView = DashboardCardInnerErrorView(message: message, canRetry: retry)
126+
errorView.delegate = self
127+
errorView.translatesAutoresizingMaskIntoConstraints = false
128+
tableView.addSubview(withFadeAnimation: errorView)
129+
tableView.pinSubviewToSafeArea(errorView)
130+
self.errorView = errorView
131+
132+
// Force the table view to recalculate its height
133+
_ = tableView.intrinsicContentSize
134+
}
110135
}
111136

112137
// MARK: - EditorAnalyticsProperties
@@ -126,6 +151,14 @@ extension PostsCardViewController: EditorAnalyticsProperties {
126151
}
127152
}
128153

154+
// MARK: - DashboardCardInnerErrorViewDelegate
155+
156+
extension PostsCardViewController: DashboardCardInnerErrorViewDelegate {
157+
func retry() {
158+
viewModel.retry()
159+
}
160+
}
161+
129162
// MARK: - PostCardTableView
130163

131164
extension NSNotification.Name {

WordPress/Classes/ViewRelated/Blog/Blog Dashboard/Cards/Posts/PostsCardViewModel.swift

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ protocol PostsCardView: AnyObject {
77

88
func showLoading()
99
func hideLoading()
10+
func showError(message: String, retry: Bool)
1011
}
1112

1213
/// Responsible for populating a table view with posts
@@ -52,6 +53,11 @@ class PostsCardViewModel: NSObject {
5253
}
5354
}
5455

56+
func retry() {
57+
viewController?.showLoading()
58+
sync()
59+
}
60+
5561
/// Set up the view model to be ready for use
5662
func viewDidLoad() {
5763
viewController?.showLoading()
@@ -73,6 +79,10 @@ class PostsCardViewModel: NSObject {
7379
// MARK: - Private methods
7480

7581
private extension PostsCardViewModel {
82+
private var numberOfPosts: Int {
83+
fetchedResultsController.fetchedObjects?.count ?? 0
84+
}
85+
7686
func createFetchedResultsController() {
7787
fetchedResultsController?.delegate = nil
7888
fetchedResultsController = nil
@@ -121,17 +131,36 @@ private extension PostsCardViewModel {
121131
ofType: .post,
122132
with: options,
123133
for: blog,
124-
success: { _ in
134+
success: { [weak self] _ in
135+
if self?.numberOfPosts == 0 {
136+
self?.showEmptyPostsError()
137+
}
138+
}, failure: { [weak self] _ in
139+
if self?.numberOfPosts == 0 {
140+
self?.showLoadingFailureError()
141+
}
142+
})
143+
}
125144

126-
}, failure: { (error: Error?) -> () in
145+
func showEmptyPostsError() {
146+
viewController?.hideLoading()
147+
viewController?.showError(message: Strings.noPostsMessage, retry: false)
148+
}
127149

128-
})
150+
func showLoadingFailureError() {
151+
viewController?.hideLoading()
152+
viewController?.showError(message: Strings.loadingFailure, retry: true)
129153
}
130154

131155
enum Constants {
132156
static let numberOfPosts = 3
133157
static let numberOfPostsToSync: NSNumber = 4
134158
}
159+
160+
enum Strings {
161+
static let noPostsMessage = NSLocalizedString("You don't have any posts", comment: "Displayed when the user views the dashboard posts card but they have no posts")
162+
static let loadingFailure = NSLocalizedString("Unable to load posts right now.", comment: "Message for when posts fail to load on the dashboard")
163+
}
135164
}
136165

137166
// MARK: - UITableViewDataSource

WordPress/Classes/ViewRelated/Blog/QuickStartSettings.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,7 @@ final class QuickStartSettings {
3535
}
3636

3737
private func promptWasDismissedKey(for blog: Blog) -> String? {
38-
guard let siteID = blog.dotComID?.intValue else {
39-
return nil
40-
}
38+
let siteID = blog.dotComID?.intValue ?? 0
4139
return "QuickStartPromptWasDismissed-\(siteID)"
4240
}
4341

WordPress/Classes/ViewRelated/Post/PostCompactCell.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,4 +232,8 @@ extension PostCompactCell {
232232
trailingContentConstraint.constant = Constants.margin
233233
headerStackView.spacing = Constants.margin
234234
}
235+
236+
func hideSeparator() {
237+
separator.isHidden = true
238+
}
235239
}

WordPress/Classes/ViewRelated/Stats/SiteStatsDashboardViewController.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,10 +194,11 @@ private extension SiteStatsDashboardViewController {
194194
let selectedPeriodChanged = currentSelectedPeriod != oldSelectedPeriod
195195
let previousSelectedPeriodWasInsights = oldSelectedPeriod == .insights
196196
let pageViewControllerIsEmpty = pageViewController?.viewControllers?.isEmpty ?? true
197+
let isGrowAudienceShowingOnInsights = insightsTableViewController.isGrowAudienceShowing
197198

198199
switch currentSelectedPeriod {
199200
case .insights:
200-
if selectedPeriodChanged || pageViewControllerIsEmpty {
201+
if selectedPeriodChanged || pageViewControllerIsEmpty || isGrowAudienceShowingOnInsights {
201202
pageViewController?.setViewControllers([insightsTableViewController],
202203
direction: .forward,
203204
animated: false)

WordPress/WordPress.xcodeproj/project.pbxproj

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1437,6 +1437,8 @@
14371437
8B821F3C240020E2006B697E /* PostServiceUploadingListTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B821F3B240020E2006B697E /* PostServiceUploadingListTests.swift */; };
14381438
8B85AEDA259230FC00ADBEC9 /* ABTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B85AED9259230FC00ADBEC9 /* ABTest.swift */; };
14391439
8B8C814D2318073300A0E620 /* BasePostTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B8C814C2318073300A0E620 /* BasePostTests.swift */; };
1440+
8B8E50B627A4692000C89979 /* DashboardCardInnerErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B8E50B527A4692000C89979 /* DashboardCardInnerErrorView.swift */; };
1441+
8B8E50B727A4692000C89979 /* DashboardCardInnerErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B8E50B527A4692000C89979 /* DashboardCardInnerErrorView.swift */; };
14401442
8B8FE8582343955500F9AD2E /* PostAutoUploadMessages.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B8FE8562343952B00F9AD2E /* PostAutoUploadMessages.swift */; };
14411443
8B93412F257029F60097D0AC /* FilterChipButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B93412E257029F50097D0AC /* FilterChipButton.swift */; };
14421444
8B93856E22DC08060010BF02 /* PageListSectionHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B93856D22DC08060010BF02 /* PageListSectionHeaderView.swift */; };
@@ -6079,6 +6081,7 @@
60796081
8B821F3B240020E2006B697E /* PostServiceUploadingListTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostServiceUploadingListTests.swift; sourceTree = "<group>"; };
60806082
8B85AED9259230FC00ADBEC9 /* ABTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ABTest.swift; sourceTree = "<group>"; };
60816083
8B8C814C2318073300A0E620 /* BasePostTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BasePostTests.swift; sourceTree = "<group>"; };
6084+
8B8E50B527A4692000C89979 /* DashboardCardInnerErrorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashboardCardInnerErrorView.swift; sourceTree = "<group>"; };
60826085
8B8FE8562343952B00F9AD2E /* PostAutoUploadMessages.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostAutoUploadMessages.swift; sourceTree = "<group>"; };
60836086
8B93412E257029F50097D0AC /* FilterChipButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilterChipButton.swift; sourceTree = "<group>"; };
60846087
8B93856D22DC08060010BF02 /* PageListSectionHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageListSectionHeaderView.swift; sourceTree = "<group>"; };
@@ -11320,6 +11323,7 @@
1132011323
isa = PBXGroup;
1132111324
children = (
1132211325
8B4DDF24278F3AF60022494D /* Posts */,
11326+
8B8E50B427A468E800C89979 /* Helpers */,
1132311327
);
1132411328
path = Cards;
1132511329
sourceTree = "<group>";
@@ -11374,6 +11378,15 @@
1137411378
path = "AB Testing";
1137511379
sourceTree = "<group>";
1137611380
};
11381+
8B8E50B427A468E800C89979 /* Helpers */ = {
11382+
isa = PBXGroup;
11383+
children = (
11384+
8B8E50B527A4692000C89979 /* DashboardCardInnerErrorView.swift */,
11385+
);
11386+
name = Helpers;
11387+
path = Posts/Helpers;
11388+
sourceTree = "<group>";
11389+
};
1137711390
8B93412D257029E30097D0AC /* Filter */ = {
1137811391
isa = PBXGroup;
1137911392
children = (
@@ -18171,6 +18184,7 @@
1817118184
C76F48EE25BA20EF00BFEC87 /* JetpackScanHistoryCoordinator.swift in Sources */,
1817218185
17FCA6811FD84B4600DBA9C8 /* NoticeStore.swift in Sources */,
1817318186
9A162F2921C271D300FDC035 /* RevisionBrowserState.swift in Sources */,
18187+
8B8E50B627A4692000C89979 /* DashboardCardInnerErrorView.swift in Sources */,
1817418188
FAADE43A26159B2800BF29FE /* AppConstants.swift in Sources */,
1817518189
1751E5911CE0E552000CA08D /* KeyValueDatabase.swift in Sources */,
1817618190
8BF0B607247D88EB009A7457 /* UITableViewCell+enableDisable.swift in Sources */,
@@ -19795,6 +19809,7 @@
1979519809
93CDC72226CD342900C8A3A8 /* DestructiveAlertHelper.swift in Sources */,
1979619810
FABB22612602FC2C00C8785C /* WPStyleGuide+AlertView.swift in Sources */,
1979719811
DC76668426FD9AC9009254DD /* TimeZoneRow.swift in Sources */,
19812+
8B8E50B727A4692000C89979 /* DashboardCardInnerErrorView.swift in Sources */,
1979819813
FABB22622602FC2C00C8785C /* ErrorStateViewConfiguration.swift in Sources */,
1979919814
46B1A16C26A774E500F058AE /* CollapsableHeaderView.swift in Sources */,
1980019815
FABB22632602FC2C00C8785C /* UIFont+Styles.swift in Sources */,

0 commit comments

Comments
 (0)