Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Notifications Refresh (Phase 1) #22524

Merged
merged 185 commits into from
Feb 28, 2024
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
185 commits
Select commit Hold shift + click to select a range
11a6fac
This is an empty commit
salimbraksa Feb 1, 2024
0c5c0d4
This is an empty commit
salimbraksa Feb 1, 2024
87e4f14
Add Icon to Design System module
salimbraksa Feb 1, 2024
4a24fd3
Group mark all as read and settings buttons in a menu
salimbraksa Feb 5, 2024
e8bdff2
Add gearshape and checkmark icons to Icon Design System module
salimbraksa Feb 5, 2024
35f7512
Resolve an issue where the Mark All As Read button wasn't disabled af…
salimbraksa Feb 5, 2024
2ea3c54
Refactor menu items creation to UIDeferredMenuElement
salimbraksa Feb 6, 2024
83799cd
Update NotificationSyncMediator.swift
salimbraksa Feb 6, 2024
08a5b2e
Change vertical ellipsis to horizontal
salimbraksa Feb 6, 2024
c9e3981
Update localized strings key to Reverse-DNS format
salimbraksa Feb 6, 2024
0307ae7
Execute mark notifications as read on the main thread
salimbraksa Feb 6, 2024
feaf5d9
Track event when menu button is tapped
salimbraksa Feb 6, 2024
6c5e123
Group notifications screen navigation bar button items into an overfl…
salimbraksa Feb 6, 2024
15d0e56
Update notifications list heading
salimbraksa Feb 6, 2024
c2e313b
Replace hardcoded padding values with Length type from the DesignSystem
salimbraksa Feb 6, 2024
b114438
Add `AvatarView`
alpavanoglu Feb 7, 2024
a96552a
Add `Constants` to remove magic numbers
alpavanoglu Feb 7, 2024
d88a9a5
Update margins for AvatarsView
alpavanoglu Feb 7, 2024
f095485
Update double avatar circle sizes
alpavanoglu Feb 7, 2024
0b14e82
Add avatar border
alpavanoglu Feb 7, 2024
8814ce6
Add `actionIcon`
alpavanoglu Feb 7, 2024
c60b600
Remove testing background color
alpavanoglu Feb 7, 2024
1bb6c4d
Hide bottom tab bar for notification details screens
justtwago Feb 7, 2024
eae5302
Merge branch 'feature/notifications_refresh_p1' into task/22474-hide-…
Feb 7, 2024
9459828
Fix background color in dark mode
salimbraksa Feb 8, 2024
5302cff
Refactor `Content` to allow multiple styles
alpavanoglu Feb 9, 2024
1f05244
Add border color customization to `AvatarsView`
alpavanoglu Feb 9, 2024
ee9d445
Add convenience init to `AvatarsView.Style`
alpavanoglu Feb 9, 2024
4c974be
Add Gravatar support to `AvatarsView`
alpavanoglu Feb 9, 2024
eb78535
Increase line limit on error text to 2
alpavanoglu Feb 9, 2024
5b76642
[Notifications P1] Notifications Cell Content Rewrite (#22564)
alpavanoglu Feb 9, 2024
bb1bb3a
Implement an interface to access design system UIFonts
salimbraksa Feb 9, 2024
673ea69
Merge branch 'trunk' into feature/notifications_refresh_p1
salimbraksa Feb 9, 2024
050bc90
Sync with base branch and fix conflicts
salimbraksa Feb 9, 2024
af1effc
Fix a typo
salimbraksa Feb 9, 2024
76cc973
Update notifications list heading style (#22556)
salimbraksa Feb 12, 2024
382c489
Add `HostingTableViewCell`
alpavanoglu Feb 12, 2024
34b8640
Update header bottom padding
alpavanoglu Feb 12, 2024
2251d1b
Remove namespacing on `NotificationsTableViewCellContent`
alpavanoglu Feb 12, 2024
5d699d0
Increase padding between texts
alpavanoglu Feb 12, 2024
2939732
Add `allAvatarURLs` parsing
alpavanoglu Feb 12, 2024
47e3072
Update cell height calculation
alpavanoglu Feb 12, 2024
ac5ad17
Add placeholder image for `AvatarsView`
alpavanoglu Feb 12, 2024
f786698
Clean up `HostingTableViewController`
alpavanoglu Feb 12, 2024
2795514
Add `reuseIdentifier` constant
alpavanoglu Feb 12, 2024
93a011c
Update tableview.selectionStyle
alpavanoglu Feb 12, 2024
3ec738a
Group Comment related files in one folder
salimbraksa Feb 12, 2024
53295d7
Refactor notification comment detail screen to support different view…
salimbraksa Feb 12, 2024
ec1451c
Revert allowsModeration changes
salimbraksa Feb 12, 2024
6e82d1f
Remove file reference
salimbraksa Feb 12, 2024
9db3f13
Remove other case from Content enum
salimbraksa Feb 12, 2024
67958eb
Update a comment in updateDisplayedComment method
salimbraksa Feb 13, 2024
030df9b
Use the new comment table header view
salimbraksa Feb 13, 2024
fe981f5
Revert allow moderation change
salimbraksa Feb 13, 2024
080840b
Add test case for `allAvatarURLs`
alpavanoglu Feb 13, 2024
2b1626e
Add deleted cell logic
alpavanoglu Feb 13, 2024
7ff1a21
Fix redundant bottom padding for a notification details screen
justtwago Feb 13, 2024
7b06774
Refactor makeNewContent to improve readaibility
salimbraksa Feb 14, 2024
028df24
Resolve an edge case where the Comment Detail might be shown even tho…
salimbraksa Feb 14, 2024
1e2d7b7
Add documentation for the Content enum
salimbraksa Feb 14, 2024
0ee88c7
Fix triple avatar cell vertical alignment
alpavanoglu Feb 14, 2024
ee81dd7
Add `invalidateIntrinsicContentSize` to `HostingTableViewCell`
alpavanoglu Feb 14, 2024
f56215d
Resolve another edge where the comment detail could be shown instead …
salimbraksa Feb 14, 2024
7aafea5
Update test json to fix test
alpavanoglu Feb 14, 2024
9abb1cc
Remove force-unwrap & reduce boilerplate in if-else
alpavanoglu Feb 14, 2024
49367c1
Remove redundant layout calls
alpavanoglu Feb 14, 2024
8859fcf
Replace spacers with padding on `AvatarsView`
alpavanoglu Feb 14, 2024
c4657ca
Replace `title` as `AttributedText` to allow reply icon to appear
alpavanoglu Feb 14, 2024
b132b27
Add reblog notfiication type
salimbraksa Feb 14, 2024
37a3215
[Notifications P1] Replace Notifications Cell Content (#22593)
salimbraksa Feb 14, 2024
7448578
Improve NotificationsViewController readability
justtwago Feb 14, 2024
bebaf6e
Minor code tweak
salimbraksa Feb 15, 2024
9ce7290
Merge branch 'trunk' of github.com:wordpress-mobile/WordPress-iOS int…
alpavanoglu Feb 15, 2024
a79487e
Bring user straight to reader comments s creen when notification comm…
salimbraksa Feb 15, 2024
dcd93af
Merge branch 'feature/notifications_refresh_p1' into task/22473-share…
salimbraksa Feb 15, 2024
714daea
Fix build error
salimbraksa Feb 15, 2024
f79710f
Merge branch 'feature/notifications_refresh_p1' into task/22473-share…
salimbraksa Feb 15, 2024
1a39232
Update notification row inline action API
salimbraksa Feb 15, 2024
7f8fed9
Update notification row preview example
salimbraksa Feb 15, 2024
dbeed32
Use if-statement instead of guard in NotificationsViewController
Feb 15, 2024
204f2bb
[Notifications P1] Hide the bottom tab bar for all notification detai…
Feb 15, 2024
5fae05c
Dynamic notification row alignment
salimbraksa Feb 15, 2024
d10b6de
Fix an issue in the SizeCalculator where it wasn't not working properly
salimbraksa Feb 15, 2024
65005cd
Sync with trunk and fix conflicts
salimbraksa Feb 16, 2024
7ad4218
Fix build errors
salimbraksa Feb 16, 2024
44986c5
Notifications row inline action groundwork (#22616)
salimbraksa Feb 16, 2024
394b2f4
Update: only include users' media when parsing notification for avatars
hassaanelgarem Feb 19, 2024
e27be55
Update: update test data to include non-user media
hassaanelgarem Feb 19, 2024
5f71ae0
Merge branch 'trunk' of github.com:wordpress-mobile/WordPress-iOS int…
alpavanoglu Feb 20, 2024
5031b5d
Replace `AsyncImage` with the new `CachedAsyncImage`
alpavanoglu Feb 20, 2024
5fb77c9
Fix showing non-user media as an avatar in Notifications screen (#22630)
alpavanoglu Feb 20, 2024
057545d
Fix avatars horizontal padding
alpavanoglu Feb 20, 2024
bdbd1cf
Merge branch 'feature/notifications_refresh_p1' of github.com:wordpre…
alpavanoglu Feb 20, 2024
b73fa55
Limit max height
alpavanoglu Feb 20, 2024
e25b0a4
Refactor notification cell configuration logic
salimbraksa Feb 20, 2024
3631319
Add block share icon to Design System library
salimbraksa Feb 20, 2024
4d57e5a
Add star inline action for new posts and comments
salimbraksa Feb 20, 2024
a72788c
Improve dynamic text UI & set description line limit to 1
alpavanoglu Feb 20, 2024
6651f05
Present activity controller when share action is tapped
salimbraksa Feb 20, 2024
08c1e47
Track analytics event when share action is tapped
salimbraksa Feb 21, 2024
fd71a2c
Report error if the notification post cannot be shared
salimbraksa Feb 21, 2024
b590e79
[Notifications P1] Replace `AsyncImage` with `CachedAsyncImage` (#22643)
alpavanoglu Feb 21, 2024
6f83df1
Merge branch 'feature/notifications_refresh_p1' of github.com:wordpre…
alpavanoglu Feb 21, 2024
e943d73
Add y offset to text to align with image
alpavanoglu Feb 21, 2024
4081f8a
Refactor share inline action logic
salimbraksa Feb 21, 2024
35f36fa
Change like button style when tapped
salimbraksa Feb 21, 2024
e08faee
Update inline action icon without animation
salimbraksa Feb 21, 2024
d010754
Move notification cell configuration logic to its own file
salimbraksa Feb 21, 2024
a602e19
Hide the like comment action for now
salimbraksa Feb 21, 2024
9aa0ce8
Add logic to toggle notification post like state
salimbraksa Feb 21, 2024
b12a1b9
[Notifications P1] Improve row UI for accessibility (#22649)
alpavanoglu Feb 22, 2024
e766fd9
Add pragma marks
salimbraksa Feb 22, 2024
838765b
Add a message when sharing a post from a notification
hassaanelgarem Feb 22, 2024
6245912
Update header style as `grouped`
alpavanoglu Feb 22, 2024
a4e35aa
Update notification post like status locally
salimbraksa Feb 22, 2024
3b4a5d7
Enable default selection style for split notification screen
justtwago Feb 22, 2024
f46cf21
Change selection style accordingly to the screen's horizontal size
justtwago Feb 22, 2024
aab45b1
Modify the notifications header paddings accordingly to designs
justtwago Feb 22, 2024
acb4ba8
Update post liked status remotely
salimbraksa Feb 22, 2024
8bec16b
Toggle comment liked status locally
salimbraksa Feb 22, 2024
5412679
[Notifications P1] Update header style so header won't float (#22680)
alpavanoglu Feb 22, 2024
5f623c7
Update the comment service API to return the new liked status
salimbraksa Feb 22, 2024
8e64b96
Add method to fetch post from local or remote
salimbraksa Feb 23, 2024
945edf7
Update: truncate long push notifications
hassaanelgarem Feb 23, 2024
9fd9c43
Update comment liked status remotely
salimbraksa Feb 23, 2024
e12b749
Remove comment like logic
salimbraksa Feb 23, 2024
a3192bc
Remove temporary variable
salimbraksa Feb 23, 2024
99bbcef
Revert comment like logic
salimbraksa Feb 23, 2024
bfb8654
Fix compile error
salimbraksa Feb 23, 2024
5ecd857
Merge branch 'feature/notifications_refresh_p1' into task/22473-share…
salimbraksa Feb 23, 2024
8e3bc5e
Add notifications inline action for share an own published post (#22652)
salimbraksa Feb 23, 2024
6625943
Merge branch 'feature/notifications_refresh_p1' into task/22473-share…
salimbraksa Feb 23, 2024
a165b9e
Sync with base branch and fix conflicts
salimbraksa Feb 23, 2024
9dd1b75
Add Like Comment Inline Action
salimbraksa Feb 23, 2024
b89c013
Remove temporary notification variable
salimbraksa Feb 23, 2024
c30f4b4
Reduce tap padding on section header
alpavanoglu Feb 23, 2024
c0f36c2
Update background color as .systemBackground
alpavanoglu Feb 23, 2024
926f6f3
Add: function in `NotificationSyncMediator` to like post
hassaanelgarem Feb 23, 2024
b602f9a
Update: use new function to like posts
hassaanelgarem Feb 23, 2024
72cd102
Update: revert unneeded changes related to reader service
hassaanelgarem Feb 23, 2024
5c4b8e9
Remove: legacy unneeded code
hassaanelgarem Feb 23, 2024
1330e92
Update: add back code for inline prompts
hassaanelgarem Feb 23, 2024
47ee2ec
Update: track liked or unliked property in like action event
hassaanelgarem Feb 23, 2024
79b9783
Tests: fix build errors
hassaanelgarem Feb 23, 2024
12106e7
Merge branch 'task/22466-like-post-inline-action' into task/22466-lik…
hassaanelgarem Feb 23, 2024
c9c3c3e
Update: implement comment likes
hassaanelgarem Feb 23, 2024
b0c5c19
Update: track liked or unliked
hassaanelgarem Feb 23, 2024
9d46017
Center trailing icon vertically
alpavanoglu Feb 23, 2024
a345b88
Update: Introduce `LikeableNotification` and implement it for post likes
hassaanelgarem Feb 23, 2024
63dd759
Update: Implement `LikeableNotification` for comment likes
hassaanelgarem Feb 23, 2024
ee5c2b3
Update: revert unneeded changes related to comments service
hassaanelgarem Feb 23, 2024
2919ee3
Tests: fix build errors
hassaanelgarem Feb 23, 2024
557f573
[Notifications] Add Like Comment Inline Action (#22691)
hassaanelgarem Feb 23, 2024
73a58c0
Rename NotificationsTableHeaderView Style to HeaderPosition
justtwago Feb 23, 2024
f6f982f
Update: removing unneeded alignment
hassaanelgarem Feb 23, 2024
8d2254a
Update: rename and add docs for parsed notifications
hassaanelgarem Feb 23, 2024
830256c
Replace top and bottom padding to vertical in NotificationsTableViewC…
justtwago Feb 23, 2024
d5d7e52
Merge branch 'feature/notifications_refresh_p1' into fix/22672-add-mi…
Feb 23, 2024
5f06283
Rename `like` to `isLike`
hassaanelgarem Feb 23, 2024
d0e0895
[Notifications P1] Section header spacing change (#22696)
alpavanoglu Feb 23, 2024
677829c
Update WordPress/Classes/Extensions/String+Truncate.swift
hassaanelgarem Feb 23, 2024
f999a4a
Refactor `CommentNotification` & ` NewPostNotification` to have non-n…
alpavanoglu Feb 23, 2024
cef6a48
Update: condense horizontal whitespace in notifications
hassaanelgarem Feb 23, 2024
7011d43
Push Notifications: Properly truncate long notifications (#22687)
hassaanelgarem Feb 23, 2024
f0163e3
Merge branch 'feature/notifications_refresh_p1' into fix/22672-add-mi…
Feb 23, 2024
159b6f1
[Notifications P1] Add missing notification selection color for a spl…
Feb 23, 2024
9464cd0
Add feature release note
alpavanoglu Feb 24, 2024
f64469f
Merge branch 'feature/notifications_refresh_p1' into task/22466-like-…
hassaanelgarem Feb 25, 2024
d785ee6
Update padding around 3avatar view & section headers
alpavanoglu Feb 26, 2024
55200cd
Revert "Refactor `CommentNotification` & ` NewPostNotification` to ha…
hassaanelgarem Feb 26, 2024
1796fe8
Remove `HeaderPosition`
alpavanoglu Feb 26, 2024
fbf7a1d
[Notifications P1] Update spacings around 3-avatar row & section head…
alpavanoglu Feb 26, 2024
8edc127
[Notifications] Add Like Post and Comment Inline Actions (#22688)
alpavanoglu Feb 26, 2024
1e8f331
Unify vertical padding for a notifications header
justtwago Feb 26, 2024
e87bafd
Fix notifications header vertical padding (#22704)
Feb 26, 2024
8c44c36
Update: fix UI glitch when liking a notification
hassaanelgarem Feb 27, 2024
8040665
Update: invalidate notification when it's changed from details view
hassaanelgarem Feb 27, 2024
59d7de3
Update: set notification ID on reader coordinator
hassaanelgarem Feb 27, 2024
c75b704
Update: update comment and post like status locally after liking from…
hassaanelgarem Feb 27, 2024
81810ee
Merge branch 'trunk' into feature/notifications_refresh_p1
hassaanelgarem Feb 27, 2024
2c625bc
Merge branch 'feature/notifications_refresh_p1' into task/22466-like-…
hassaanelgarem Feb 27, 2024
a948db1
Update: Fix build error
hassaanelgarem Feb 27, 2024
d907064
Merge branch 'feature/notifications_refresh_p1' into task/22466-like-…
hassaanelgarem Feb 27, 2024
bd38f0e
Update: rename operation completion handler
hassaanelgarem Feb 27, 2024
f6202c5
Notifications: Fix multiple with issues with the new like inline acti…
hassaanelgarem Feb 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Modules/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ let package = Package(
name: "\(jetpackStatsWidgetsCoreName)Tests",
dependencies: [.target(name: jetpackStatsWidgetsCoreName)]
),
.testTarget(
name: "\(designSystemName)Tests",
dependencies: [.target(name: designSystemName)]
),
.target(name: designSystemName)
]
)
32 changes: 32 additions & 0 deletions Modules/Sources/DesignSystem/Foundation/IconName.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import UIKit
import SwiftUI

/// `Icon` provides a namespace for icon identifiers.
///
/// The naming convention follows the SF Symbols guidelines, enhancing consistency and readability.
/// Each icon name is a dot-syntax representation of the icon's hierarchy and style.
///
/// For example, `ellipsis.vertical` represents a vertical ellipsis icon.
public enum IconName: String, CaseIterable {
case ellipsisHorizontal = "ellipsis.horizontal"
Copy link
Contributor

@kean kean Feb 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be worth reading out to the infra team and asking them to integrate SwiftGen that can generate the similar code for accessing assets automatically. It will reduce the amount of manual work and provide build-time checks for the availability of resources.

Btw, what does the DS mean?

Copy link
Contributor Author

@salimbraksa salimbraksa Feb 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be worth reading out to the infra team and asking them to integrate SwiftGen that can generate the similar code for accessing assets automatically.

Agreed, what do you think @mokagio?

Btw, what does the DS mean?

It stands for Design System ✨

We wanted to namespace this design system so it doesn't conflict with the old one. But imo, it would be great to come up with a proper name for this Design System, instead of just DS.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@salimbraksa @kean I think integrating SwiftGet is a great idea :)

case checkmark
case gearshapeFill = "gearshape.fill"
}

// MARK: - Load Image

public extension UIImage {
enum DS {
public static func icon(named name: IconName, with configuration: UIImage.Configuration? = nil) -> UIImage? {
return UIImage(named: name.rawValue, in: .module, with: configuration)
}
}
}

public extension Image {
enum DS {
public static func icon(named name: IconName) -> Image {
return Image(name.rawValue, bundle: .module)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"images" : [
{
"filename" : "checkmark.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "template"
}
}
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"images" : [
{
"filename" : "more-horizontal-mobile.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "template"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"images" : [
{
"filename" : "cog.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true,
"template-rendering-intent" : "template"
}
}
Binary file not shown.
12 changes: 12 additions & 0 deletions Modules/Tests/DesignSystemTests/IconTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import XCTest
import DesignSystem
import SwiftUI

final class IconTests: XCTestCase {

func testCanLoadAllIconsAsUIImage() throws {
for icon in IconName.allCases {
let _ = try XCTUnwrap(UIImage.DS.icon(named: icon))
}
}
}
32 changes: 24 additions & 8 deletions WordPress/Classes/Services/NotificationSyncMediator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -150,43 +150,59 @@ final class NotificationSyncMediator: NotificationSyncMediatorProtocol {

/// Marks a Notification as Read.
///
/// - Note: This method should only be used on the main thread.
/// - Note: This method is called on the main thread.
///
/// - Parameters:
/// - notification: The notification that was just read.
/// - completion: Callback to be executed on completion.
///
func markAsRead(_ notification: Notification, completion: ((Error?)-> Void)? = nil) {
mark([notification], asRead: true, completion: completion)
Task { @MainActor in
mark([notification], asRead: true, completion: completion)
}
}

/// Marks an array of notifications as Read.
///
/// - Note: This method should only be used on the main thread.
/// - Note: This method is called on the main thread.
///
/// - Parameters:
/// - notifications: Notifications that were marked as read.
/// - completion: Callback to be executed on completion.
///
func markAsRead(_ notifications: [Notification], completion: ((Error?)-> Void)? = nil) {
mark(notifications, asRead: true, completion: completion)
Task { @MainActor in
mark(notifications, asRead: true, completion: completion)
}
}

/// Marks a Notification as Unead.
///
/// - Note: This method should only be used on the main thread.
/// - Note: This method is called on the main thread.
///
/// - Parameters:
/// - notification: The notification that should be marked unread.
/// - completion: Callback to be executed on completion.
///
func markAsUnread(_ notification: Notification, completion: ((Error?)-> Void)? = nil) {
mark([notification], asRead: false, completion: completion)
markAsUnread([notification], completion: completion)
}

private func mark(_ notifications: [Notification], asRead read: Bool = true, completion: ((Error?)-> Void)? = nil) {
assert(Thread.isMainThread)
/// Marks a Notification as Unread.
///
/// - Note: This method is called on the main thread.
///
/// - Parameters:
/// - notifications: The notifications that should be marked unread.
/// - completion: Callback to be executed on completion.
///
func markAsUnread(_ notifications: [Notification], completion: ((Error?)-> Void)? = nil) {
Task { @MainActor in
mark(notifications, asRead: false, completion: completion)
}
}

@MainActor private func mark(_ notifications: [Notification], asRead read: Bool = true, completion: ((Error?)-> Void)? = nil) {
let noteIDs = notifications.map {
$0.notificationId
}
Expand Down
3 changes: 3 additions & 0 deletions WordPress/Classes/Utility/Analytics/WPAnalyticsEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,7 @@ import Foundation
case notificationsMarkAllReadTapped
case notificationMarkAsReadTapped
case notificationMarkAsUnreadTapped
case notificationMenuTapped

// Sharing Buttons
case sharingButtonsEditSharingButtonsToggled
Expand Down Expand Up @@ -1142,6 +1143,8 @@ import Foundation
return "notification_mark_as_read_tapped"
case .notificationMarkAsUnreadTapped:
return "notification_mark_as_unread_tapped"
case .notificationMenuTapped:
return "notification_menu_tapped"

// Sharing
case .sharingButtonsEditSharingButtonsToggled:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import Foundation

extension NotificationsViewController {

enum Strings {
enum NavigationBar {
static let notificationSettingsActionTitle = NSLocalizedString(
"notificationsViewController.navigationBar.action.settings",
value: "Notification Settings",
comment: "Link to Notification Settings section"
)
static let markAllAsReadActionTitle = NSLocalizedString(
"notificationsViewController.navigationBar.action.markAllAsRead",
value: "Mark All As Read",
comment: "Marks all notifications under the filter as read"
)
static let menuButtonAccessibilityLabel = NSLocalizedString(
"notificationsViewController.navigationBar.menu.accessibilityLabel",
value: "Navigation Bar Menu Button",
comment: "Accessibility label for the navigation bar menu button"
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -103,36 +103,6 @@ class NotificationsViewController: UIViewController, UIViewControllerRestoration
return indicator
}()

/// Notification Settings button
private lazy var settingsBarButtonItem: UIBarButtonItem = {
let settingsButton = UIBarButtonItem(
image: .gridicon(.cog),
style: .plain,
target: self,
action: #selector(showNotificationSettings)
)
settingsButton.accessibilityLabel = NSLocalizedString(
"Notification Settings",
comment: "Link to Notification Settings section"
)
return settingsButton
}()

/// Mark All As Read button
private lazy var markAllAsReadBarButtonItem: UIBarButtonItem = {
let markButton = UIBarButtonItem(
image: .gridicon(.checkmark),
style: .plain,
target: self,
action: #selector(showMarkAllAsReadConfirmation)
)
markButton.accessibilityLabel = NSLocalizedString(
"Mark All As Read",
comment: "Marks all notifications under the filter as read"
)
return markButton
}()

/// Used by JPScrollViewDelegate to send scroll position
internal let scrollViewTranslationPublisher = PassthroughSubject<Bool, Never>()

Expand Down Expand Up @@ -199,7 +169,6 @@ class NotificationsViewController: UIViewController, UIViewControllerRestoration

// Refresh the UI
reloadResultsControllerIfNeeded()
updateMarkAllAsReadButton()

if !splitViewControllerIsHorizontallyCompact {
reloadTableViewPreservingSelection()
Expand Down Expand Up @@ -528,6 +497,7 @@ class NotificationsViewController: UIViewController, UIViewControllerRestoration
// MARK: - User Interface Initialization
//
private extension NotificationsViewController {

func setupNavigationBar() {
navigationController?.navigationBar.prefersLargeTitles = false
navigationItem.largeTitleDisplayMode = .never
Expand All @@ -540,15 +510,57 @@ private extension NotificationsViewController {
}

func updateNavigationItems() {
var barItems: [UIBarButtonItem] = []
let moreMenuItems = UIDeferredMenuElement.uncached { [weak self] completion in
guard let self else {
completion([])
return
}
WPAnalytics.track(.notificationMenuTapped)
completion(self.makeMoreMenuElements())
}
self.navigationItem.rightBarButtonItem = {
let menu = UIMenu(children: [moreMenuItems])
let button = UIBarButtonItem(
image: UIImage.DS.icon(named: .ellipsisHorizontal),
menu: menu
)
button.accessibilityLabel = Strings.NavigationBar.menuButtonAccessibilityLabel
return button
}()
}

if shouldDisplaySettingsButton {
barItems.append(settingsBarButtonItem)
}
func makeMoreMenuElements() -> [UIAction] {
// Mark All As Read
let markAllAsRead: UIAction? = { () -> UIAction? in
guard let notes = tableViewHandler.resultsController?.fetchedObjects as? [Notification] else {
return nil
}
let isEnabled = notes.first { !$0.read } != nil
let attributes = isEnabled ? UIAction.Attributes(rawValue: 0) : .disabled
return UIAction(
title: Strings.NavigationBar.markAllAsReadActionTitle,
image: .DS.icon(named: .checkmark),
attributes: attributes
) { [weak self] _ in
self?.showMarkAllAsReadConfirmation()
}
}()

barItems.append(markAllAsReadBarButtonItem)
// Notifications Settings
let settings: UIAction? = { () -> UIAction? in
guard shouldDisplaySettingsButton else {
return nil
}
return UIAction(
title: Strings.NavigationBar.notificationSettingsActionTitle,
image: .DS.icon(named: .gearshapeFill)
) { [weak self] _ in
self?.showNotificationSettings()
}
}()

navigationItem.setRightBarButtonItems(barItems, animated: false)
// Return
return [markAllAsRead, settings].compactMap { $0 }
}

@objc func closeNotificationSettings() {
Expand Down Expand Up @@ -1074,12 +1086,11 @@ private extension NotificationsViewController {
!$0.read
}

NotificationSyncMediator()?.markAsRead(unreadNotifications, completion: { [weak self] error in
NotificationSyncMediator()?.markAsRead(unreadNotifications, completion: { error in
let notice = Notice(
title: error != nil ? Localization.markAllAsReadNoticeFailure : Localization.markAllAsReadNoticeSuccess
)
ActionDispatcherFacade().dispatch(NoticeAction.post(notice))
self?.updateMarkAllAsReadButton()
})
}

Expand Down Expand Up @@ -1132,7 +1143,6 @@ private extension NotificationsViewController {
}

NotificationSyncMediator()?.markAsUnread(note)
updateMarkAllAsReadButton()
}

func markWelcomeNotificationAsSeenIfNeeded() {
Expand All @@ -1142,17 +1152,6 @@ private extension NotificationsViewController {
resetApplicationBadge()
}
}

func updateMarkAllAsReadButton() {
guard let notes = tableViewHandler.resultsController?.fetchedObjects as? [Notification] else {
return
}

let isEnabled = notes.first { !$0.read } != nil

markAllAsReadBarButtonItem.tintColor = isEnabled ? .primary : .textTertiary
markAllAsReadBarButtonItem.isEnabled = isEnabled
}
}

// MARK: - Unread notifications caching
Expand Down Expand Up @@ -1221,7 +1220,6 @@ private extension NotificationsViewController {
// Don't overwork!
lastReloadDate = Date()
needsReloadResults = false
updateMarkAllAsReadButton()
}

func reloadRowForNotificationWithID(_ noteObjectID: NSManagedObjectID) {
Expand Down
Loading
Loading