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: remove notification for deleted Comment #18028

Merged
merged 4 commits into from
Mar 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import UIKit
import CoreData

// Notification sent when a Comment is permanently deleted so the Notifications list (NotificationsViewController) is immediately updated.
extension NSNotification.Name {
static let NotificationCommentDeletedNotification = NSNotification.Name(rawValue: "NotificationCommentDeletedNotification")
}
let userInfoCommentIdKey = "commentID"

@objc protocol CommentDetailsDelegate: AnyObject {
func nextCommentSelected()
Expand All @@ -10,7 +15,6 @@ protocol CommentDetailsNotificationDelegate: AnyObject {
func previousNotificationTapped(current: Notification?)
func nextNotificationTapped(current: Notification?)
func commentWasModerated(for notification: Notification?)
func commentWasDeleted(for notification: Notification?)
}

class CommentDetailViewController: UIViewController {
Expand Down Expand Up @@ -684,9 +688,10 @@ private extension CommentDetailViewController {
}

func deleteButtonTapped() {
let commentID = comment.commentID
deleteComment() { [weak self] success in
if success {
self?.notifyDelegateCommentDeleted()
self?.postNotificationCommentDeleted(commentID)
// Dismiss the view since the Comment no longer exists.
self?.navigationController?.popViewController(animated: true)
}
Expand Down Expand Up @@ -858,19 +863,13 @@ private extension CommentDetailViewController {
}

func notifyDelegateCommentModerated() {
guard let notification = notification else {
return
}

notificationDelegate?.commentWasModerated(for: notification)
}

func notifyDelegateCommentDeleted() {
guard let notification = notification else {
return
}

notificationDelegate?.commentWasDeleted(for: notification)
func postNotificationCommentDeleted(_ commentID: Int32) {
NotificationCenter.default.post(name: .NotificationCommentDeletedNotification,
object: nil,
userInfo: [userInfoCommentIdKey: commentID])
}

func showActionableNotice(title: String) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -617,7 +617,7 @@ private extension NotificationsViewController {

func startListeningToCommentDeletedNotifications() {
NotificationCenter.default.addObserver(self,
selector: #selector(syncNotificationsWithModeratedComments),
selector: #selector(removeDeletedNotification),
name: .NotificationCommentDeletedNotification,
object: nil)
}
Expand Down Expand Up @@ -754,6 +754,8 @@ extension NotificationsViewController {
return
}

self.view.isUserInteractionEnabled = true

if FeatureFlag.notificationCommentDetails.enabled,
note.kind == .comment {
self.notificationCommentDetailCoordinator.createViewController(with: note) { commentDetailViewController in
Expand All @@ -768,14 +770,12 @@ extension NotificationsViewController {

commentDetailViewController.navigationItem.largeTitleDisplayMode = .never
self.showDetailViewController(commentDetailViewController, sender: nil)
self.view.isUserInteractionEnabled = true
}

return
}

self.performSegue(withIdentifier: NotificationDetailsViewController.classNameWithoutNamespaces(), sender: note)
self.view.isUserInteractionEnabled = true
}
}

Expand Down Expand Up @@ -885,19 +885,62 @@ private extension NotificationsViewController {
return notificationDeletionRequests[noteObjectID]
}


// MARK: - Notifications Deletion from CommentDetailViewController

// With the `notificationCommentDetails` feature, Comment moderation is handled by the view.
// To avoid updating the Notifications here prematurely, affecting the previous/next buttons,
// the Notifications are tracked in NotificationCommentDetailCoordinator when their comments are moderated.
// Those Notifications are updated here when the view is shown to update the list accordingly.
@objc func syncNotificationsWithModeratedComments() {
func syncNotificationsWithModeratedComments() {
selectNextAvailableNotification(ignoring: notificationCommentDetailCoordinator.notificationsCommentModerated)

notificationCommentDetailCoordinator.notificationsCommentModerated.forEach {
syncNotification(with: $0.notificationId, timeout: Syncing.pushMaxWait, success: {_ in })
}

notificationCommentDetailCoordinator.notificationsCommentModerated = []
}

@objc func removeDeletedNotification(notification: NSNotification) {
guard let userInfo = notification.userInfo,
let deletedCommentID = userInfo[userInfoCommentIdKey] as? Int32,
let notifications = tableViewHandler.resultsController.fetchedObjects as? [Notification] else {
return
}

let notification = notifications.first(where: { notification -> Bool in
guard let commentID = notification.metaCommentID else {
return false
}

return commentID.intValue == deletedCommentID
})

syncDeletedNotification(notification)
}

func syncDeletedNotification(_ notification: Notification?) {
guard let notification = notification else {
return
}

selectNextAvailableNotification(ignoring: [notification])

syncNotification(with: notification.notificationId, timeout: Syncing.pushMaxWait, success: { [weak self] notification in
self?.notificationCommentDetailCoordinator.notificationsCommentModerated.removeAll(where: { $0.notificationId == notification.notificationId })
})
}

func selectNextAvailableNotification(ignoring: [Notification]) {
// If the currently selected notification is about to be removed, find the next available and select it.
// This is only necessary for split view to prevent the details from showing for removed notifications.
if !splitViewControllerIsHorizontallyCompact,
let selectedNotification = selectedNotification,
notificationCommentDetailCoordinator.notificationsCommentModerated.contains(selectedNotification) {
ignoring.contains(selectedNotification) {

guard let notifications = tableViewHandler.resultsController.fetchedObjects as? [Notification],
let nextAvailable = notifications.first(where: { !notificationCommentDetailCoordinator.notificationsCommentModerated.contains($0) }),
let nextAvailable = notifications.first(where: { !ignoring.contains($0) }),
let indexPath = tableViewHandler.resultsController.indexPath(forObject: nextAvailable) else {
self.selectedNotification = nil
return
Expand All @@ -906,12 +949,6 @@ private extension NotificationsViewController {
self.selectedNotification = nextAvailable
tableView(tableView, didSelectRowAt: indexPath)
}

notificationCommentDetailCoordinator.notificationsCommentModerated.forEach {
syncNotification(with: $0.notificationId, timeout: Syncing.pushMaxWait, success: {_ in })
}

notificationCommentDetailCoordinator.notificationsCommentModerated = []
}

}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
import Foundation

// Notification sent when a Notification Comment is permanently deleted so the Notifications list (NotificationsViewController) is immediately updated.
extension NSNotification.Name {
static let NotificationCommentDeletedNotification = NSNotification.Name(rawValue: "NotificationCommentDeletedNotification")
}

// This facilitates showing the CommentDetailViewController within the context of Notifications.

class NotificationCommentDetailCoordinator: NSObject {
Expand Down Expand Up @@ -286,8 +281,4 @@ extension NotificationCommentDetailCoordinator: CommentDetailsNotificationDelega
notificationsCommentModerated.append(notification)
}

func commentWasDeleted(for notification: Notification?) {
NotificationCenter.default.post(name: .NotificationCommentDeletedNotification, object: nil)
}

}