Skip to content

Commit 0b41fcc

Browse files
authored
Merge pull request #5833 from selanthiraiyan/issue/4295-mark-all-reviews-as-read
Reviews screen - Mark all as read bar button: Replace checkmark button with menu button and action sheet.
2 parents 0d4ac9a + 859e44f commit 0b41fcc

File tree

3 files changed

+100
-43
lines changed

3 files changed

+100
-43
lines changed

RELEASE-NOTES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
- [**] System status report can now be viewed and copied directly from within the app. [https://github.com/woocommerce/woocommerce-ios/pull/5702]
77
- [**] Product SKU input scanner is now available as a beta feature. To try it, enable it from settings and you can scan a barcode to use as the product SKU in product inventory settings! [https://github.com/woocommerce/woocommerce-ios/pull/5695]
88
- [**] Now you chan share a payment link when creating a Simple Payments order [https://github.com/woocommerce/woocommerce-ios/pull/5819]
9+
- [*] Reviews: "Mark all as read" checkmark bar button item button replaced with menu button which launches an action sheet. Menu button is displayed only if there are unread reviews available.[https://github.com/woocommerce/woocommerce-ios/pull/5833]
910

1011
8.2
1112
-----

WooCommerce/Classes/ViewRelated/Reviews/ReviewsViewController.swift

Lines changed: 98 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@ final class ReviewsViewController: UIViewController {
1515
/// Mark all as read nav bar button
1616
///
1717
private lazy var rightBarButton: UIBarButtonItem = {
18-
let item = UIBarButtonItem(image: .checkmarkImage,
18+
let item = UIBarButtonItem(image: .ellipsisImage,
1919
style: .plain,
2020
target: self,
21-
action: #selector(markAllAsRead))
22-
item.accessibilityIdentifier = "reviews-mark-all-as-read-button"
23-
21+
action: #selector(presentMoreActions))
22+
item.accessibilityIdentifier = "reviews-open-menu-button"
23+
item.accessibilityTraits = .button
24+
item.accessibilityLabel = Localization.MenuButton.accessibilityLabel
25+
item.accessibilityHint = Localization.MenuButton.accessibilityHint
2426
return item
2527
}()
2628

@@ -132,7 +134,6 @@ final class ReviewsViewController: UIViewController {
132134
refreshTitle()
133135

134136
configureSyncingCoordinator()
135-
configureNavigationBarButtons()
136137
configureTableView()
137138
configureTableViewCells()
138139
configureResultsController()
@@ -183,21 +184,11 @@ private extension ReviewsViewController {
183184
/// Setup: TabBar
184185
///
185186
func configureTabBarItem() {
186-
tabBarItem.title = NSLocalizedString("Reviews", comment: "Title of the Reviews tab — plural form of Review")
187+
tabBarItem.title = Localization.tabBarItemTitle
187188
tabBarItem.image = .starOutlineImage()
188189
tabBarItem.accessibilityIdentifier = "tab-bar-reviews-item"
189190
}
190191

191-
/// Setup: NavigationBar Buttons
192-
///
193-
func configureNavigationBarButtons() {
194-
rightBarButton.accessibilityTraits = .button
195-
rightBarButton.accessibilityLabel = NSLocalizedString("Mark All as Read", comment: "Accessibility label for the Mark All Reviews as Read Button")
196-
rightBarButton.accessibilityHint = NSLocalizedString("Marks Every Review as Read",
197-
comment: "VoiceOver accessibility hint for the Mark All Reviews as Read Action")
198-
navigationItem.rightBarButtonItem = rightBarButton
199-
}
200-
201192
/// Setup: TableView
202193
///
203194
func configureTableView() {
@@ -232,10 +223,7 @@ private extension ReviewsViewController {
232223
}
233224

234225
func refreshTitle() {
235-
title = NSLocalizedString(
236-
"Reviews",
237-
comment: "Title that appears on top of the main Reviews screen (plural form of the word Review)."
238-
)
226+
title = Localization.title
239227
}
240228
}
241229

@@ -251,6 +239,20 @@ private extension ReviewsViewController {
251239
}
252240
}
253241

242+
/// Presents an action sheet on tapping the menu right bar button item.
243+
///
244+
@IBAction func presentMoreActions() {
245+
let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
246+
actionSheet.view.tintColor = .text
247+
248+
actionSheet.addCancelActionWithTitle(Localization.ActionSheet.cancelAction)
249+
actionSheet.addDefaultActionWithTitle(Localization.ActionSheet.markAsReadAction) { [weak self] _ in
250+
self?.presentMarkAllAsReadConfirmationAlert()
251+
}
252+
253+
present(actionSheet, animated: true)
254+
}
255+
254256
@IBAction func markAllAsRead() {
255257
ServiceLocator.analytics.track(.reviewsListReadAllTapped)
256258

@@ -274,7 +276,7 @@ private extension ReviewsViewController {
274276
tracks.track(.reviewsMarkAllReadSuccess)
275277
}
276278

277-
self.updateMarkAllReadButtonState()
279+
self.updateRightBarButtonItem()
278280
self.tableView.reloadData()
279281
}
280282
}
@@ -336,11 +338,11 @@ private extension ReviewsViewController {
336338
///
337339
func displayEmptyViewController() {
338340
let childController = emptyStateViewController
339-
let emptyStateConfig = EmptyStateViewController.Config.withLink(message: NSAttributedString(string: Localization.emptyStateMessage),
340-
image: .emptyReviewsImage,
341-
details: Localization.emptyStateDetail,
342-
linkTitle: Localization.emptyStateAction,
343-
linkURL: WooConstants.URLs.productReviewInfo.asURL())
341+
let emptyStateConfig = EmptyStateViewController.Config.withLink(message: NSAttributedString(string: Localization.EmptyState.message),
342+
image: .emptyReviewsImage,
343+
details: Localization.EmptyState.detail,
344+
linkTitle: Localization.EmptyState.action,
345+
linkURL: WooConstants.URLs.productReviewInfo.asURL())
344346

345347
// Abort if we are already displaying this childController
346348
guard childController.parent == nil,
@@ -412,7 +414,7 @@ private extension ReviewsViewController {
412414
/// Note: Just because this func runs does not guarantee `didEnter()` or `didLeave()` will run as well.
413415
///
414416
func willEnter(state: State) {
415-
updateNavBarButtonsState()
417+
updateRightBarButtonItem()
416418
}
417419

418420
/// Runs whenever the FSM enters a State.
@@ -478,16 +480,10 @@ private extension ReviewsViewController {
478480
//
479481
private extension ReviewsViewController {
480482

481-
/// Enables/disables the navbar buttons if needed
482-
///
483-
/// - Parameter filterEnabled: If true, the filter navbar buttons is enabled; if false, it's disabled
483+
/// Show the rightBarButtonItem only if there are unread reviews available.
484484
///
485-
func updateNavBarButtonsState() {
486-
updateMarkAllReadButtonState()
487-
}
488-
489-
func updateMarkAllReadButtonState() {
490-
rightBarButton.isEnabled = viewModel.hasUnreadNotifications
485+
func updateRightBarButtonItem() {
486+
navigationItem.rightBarButtonItem = viewModel.hasUnreadNotifications ? rightBarButton : nil
491487
}
492488

493489
/// Displays the `Mark all as read` Notice if the number of times it was previously displayed is lower than the
@@ -499,10 +495,26 @@ private extension ReviewsViewController {
499495
}
500496

501497
markAsReadCount += 1
502-
let message = NSLocalizedString("All reviews marked as read", comment: "Mark all reviews as read notice")
503-
let notice = Notice(title: message, feedbackType: .success)
498+
let notice = Notice(title: Localization.Notice.allReviewsMarkedAsRead, feedbackType: .success)
504499
ServiceLocator.noticePresenter.enqueue(notice: notice)
505500
}
501+
502+
/// Presents an alert which asks the user for confirmation
503+
/// before marking all reviews as read.
504+
///
505+
func presentMarkAllAsReadConfirmationAlert() {
506+
let alertController = UIAlertController(title: Localization.MarkAllAsReadAlert.title,
507+
message: Localization.MarkAllAsReadAlert.message,
508+
preferredStyle: .alert)
509+
alertController.view.tintColor = .text
510+
511+
alertController.addActionWithTitle(Localization.MarkAllAsReadAlert.cancelButtonTitle, style: .destructive)
512+
alertController.addDefaultActionWithTitle(Localization.MarkAllAsReadAlert.markAllButtonTitle) { [weak self] _ in
513+
self?.markAllAsRead()
514+
}
515+
516+
present(alertController, animated: true)
517+
}
506518
}
507519

508520

@@ -602,9 +614,53 @@ private extension ReviewsViewController {
602614
//
603615
private extension ReviewsViewController {
604616
enum Localization {
605-
static let emptyStateMessage = NSLocalizedString("Get your first reviews", comment: "Message shown in the Reviews tab if the list is empty")
606-
static let emptyStateDetail = NSLocalizedString("Capture high-quality product reviews for your store.",
607-
comment: "Detailed message shown in the Reviews tab if the list is empty")
608-
static let emptyStateAction = NSLocalizedString("Learn more", comment: "Title of button shown in the Reviews tab if the list is empty")
617+
static let title = NSLocalizedString("Reviews",
618+
comment: "Title that appears on top of the main Reviews screen (plural form of the word Review).")
619+
620+
static let tabBarItemTitle = NSLocalizedString("Reviews",
621+
comment: "Title of the Reviews tab — plural form of Review")
622+
623+
enum MenuButton {
624+
static let accessibilityLabel = NSLocalizedString("Open menu",
625+
comment: "Accessibility label for the Menu button")
626+
static let accessibilityHint = NSLocalizedString("Menu button which opens an action sheet with option to mark all reviews as read.",
627+
comment: "VoiceOver accessibility hint for the Menu button action")
628+
}
629+
630+
enum ActionSheet {
631+
static let markAsReadAction = NSLocalizedString("Mark all reviews as read",
632+
comment: "Option to mark all reviews as read from the action sheet in Reviews screen.")
633+
634+
static let cancelAction = NSLocalizedString("Cancel",
635+
comment: "Cancel the more menu action sheet in Reviews screen.")
636+
}
637+
638+
enum MarkAllAsReadAlert {
639+
static let title = NSLocalizedString("Mark all as read",
640+
comment: "Title of Alert which asks user for confirmation before marking all reviews as read.")
641+
642+
static let message = NSLocalizedString("Are you sure you want to mark all reviews as read?",
643+
comment: "Alert message to confirm a user meant to mark all reviews as read.")
644+
645+
static let cancelButtonTitle = NSLocalizedString("Cancel",
646+
comment: "Alert button title - dismisses alert, which cancels marking all as read attempt.")
647+
648+
static let markAllButtonTitle = NSLocalizedString("Mark all",
649+
comment: "Alert button title - confirms and marks all reviews as read")
650+
}
651+
652+
enum Notice {
653+
static let allReviewsMarkedAsRead = NSLocalizedString("All reviews marked as read",
654+
comment: "Mark all reviews as read notice")
655+
}
656+
657+
enum EmptyState {
658+
static let message = NSLocalizedString("Get your first reviews",
659+
comment: "Message shown in the Reviews tab if the list is empty")
660+
static let detail = NSLocalizedString("Capture high-quality product reviews for your store.",
661+
comment: "Detailed message shown in the Reviews tab if the list is empty")
662+
static let action = NSLocalizedString("Learn more",
663+
comment: "Title of button shown in the Reviews tab if the list is empty")
664+
}
609665
}
610666
}

WooCommerce/UITestsFoundation/Screens/Reviews/ReviewsScreen.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public final class ReviewsScreen: ScreenObject {
1212

1313
public init(app: XCUIApplication = XCUIApplication()) throws {
1414
try super.init(
15-
expectedElementGetters: [ { $0.buttons["reviews-mark-all-as-read-button"] } ],
15+
expectedElementGetters: [ { $0.buttons["reviews-open-menu-button"] } ],
1616
app: app
1717
)
1818
}

0 commit comments

Comments
 (0)