From 9e972b686721558fe1a80cf8fbf2783a6971b2ea Mon Sep 17 00:00:00 2001 From: Alex Grebenyuk Date: Wed, 11 Dec 2024 09:48:02 -0500 Subject: [PATCH] Enable quick access to notifications from Reader (#23882) * Enable quick access to notifications from Reader * Fix spacing * Update release notes --- RELEASE-NOTES.txt | 2 ++ .../System/Root View/ReaderPresenter.swift | 8 ++++-- .../Blog/My Site/MySiteViewController.swift | 28 ++++--------------- .../NotificationsViewController.swift | 12 ++++++++ .../ReaderDiscoverViewController.swift | 23 +++++++++++++++ .../ReaderStreamViewController.swift | 18 ++++++++++++ 6 files changed, 66 insertions(+), 25 deletions(-) diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt index 56dab2a05e25..e395c266757f 100644 --- a/RELEASE-NOTES.txt +++ b/RELEASE-NOTES.txt @@ -7,6 +7,8 @@ * [*] [internal] Update Gravatar SDK to 3.0.0 [#23701] * [*] Use the Gravatar Quick Editor to update the avatar [#23729] * [*] (Hidden under a feature flag) User Management for self-hosted sites. [#23768] +* [*] Enable quick access to notifications from Reader on iPad [#23882] +* [*] Add support for restricted posts in Reader [#23853] 25.5 ----- diff --git a/WordPress/Classes/System/Root View/ReaderPresenter.swift b/WordPress/Classes/System/Root View/ReaderPresenter.swift index fcda27c1748c..5aafb1d57644 100644 --- a/WordPress/Classes/System/Root View/ReaderPresenter.swift +++ b/WordPress/Classes/System/Root View/ReaderPresenter.swift @@ -122,13 +122,17 @@ final class ReaderPresenter: NSObject, SplitViewDisplayable { if screen == .discover { return ReaderDiscoverViewController(topic: topic) } else { - return ReaderStreamViewController.controllerWithTopic(topic) + let streamVC = ReaderStreamViewController.controllerWithTopic(topic) + streamVC.isNotificationsBarButtonEnabled = true + return streamVC } } else { return makeErrorViewController() // This should never happen } case .saved: - return ReaderStreamViewController.controllerForContentType(.saved) + let streamVC = ReaderStreamViewController.controllerForContentType(.saved) + streamVC.isNotificationsBarButtonEnabled = true + return streamVC case .search: return ReaderSearchViewController() } diff --git a/WordPress/Classes/ViewRelated/Blog/My Site/MySiteViewController.swift b/WordPress/Classes/ViewRelated/Blog/My Site/MySiteViewController.swift index 894e4d1d9742..d62931eae38b 100644 --- a/WordPress/Classes/ViewRelated/Blog/My Site/MySiteViewController.swift +++ b/WordPress/Classes/ViewRelated/Blog/My Site/MySiteViewController.swift @@ -286,33 +286,15 @@ final class MySiteViewController: UIViewController, UIScrollViewDelegate, NoSite navigationController?.navigationBar.accessibilityIdentifier = "my-site-navigation-bar" if isSidebarModeEnabled { - navigationItem.rightBarButtonItems = makeRegularClassSizeNavigationItems() - - notificationsButtonViewModel.$image.dropFirst() - .receive(on: DispatchQueue.main) // Skip on hop - .sink { [weak self] _ in - guard let self else { return } - self.navigationItem.rightBarButtonItems = self.makeRegularClassSizeNavigationItems() - }.store(in: &cancellables) + notificationsButtonViewModel.$image.sink { [weak self] in + guard let self else { return } + self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: $0, style: .plain, target: self, action: #selector(buttonShowNotificationsTapped)) + }.store(in: &cancellables) } } - private func makeRegularClassSizeNavigationItems() -> [UIBarButtonItem] { - return [ - UIBarButtonItem(image: notificationsButtonViewModel.image, style: .plain, target: self, action: #selector(buttonShowNotificationsTapped)) - ] - } - @objc private func buttonShowNotificationsTapped(_ sender: UIBarButtonItem) { - let notificationsVC = UIStoryboard(name: "Notifications", bundle: nil).instantiateInitialViewController() as! NotificationsViewController - notificationsVC.isSidebarModeEnabled = true - - let navigationVC = UINavigationController(rootViewController: notificationsVC) - navigationVC.modalPresentationStyle = .popover - navigationVC.preferredContentSize = CGSize(width: 375, height: 800) - navigationVC.popoverPresentationController?.sourceItem = sender - navigationVC.popoverPresentationController?.permittedArrowDirections = [.up] - present(navigationVC, animated: true) + NotificationsViewController.showInPopover(from: self, sourceItem: sender) } private func configureNavBarAppearance(animated: Bool) { diff --git a/WordPress/Classes/ViewRelated/Notifications/Controllers/NotificationsViewController/NotificationsViewController.swift b/WordPress/Classes/ViewRelated/Notifications/Controllers/NotificationsViewController/NotificationsViewController.swift index 55134eb1411e..210c5f54ff52 100644 --- a/WordPress/Classes/ViewRelated/Notifications/Controllers/NotificationsViewController/NotificationsViewController.swift +++ b/WordPress/Classes/ViewRelated/Notifications/Controllers/NotificationsViewController/NotificationsViewController.swift @@ -117,6 +117,18 @@ class NotificationsViewController: UIViewController, UITableViewDataSource, UITa // MARK: - View Lifecycle + static func showInPopover(from presentingVC: UIViewController, sourceItem: UIPopoverPresentationControllerSourceItem) { + let notificationsVC = UIStoryboard(name: "Notifications", bundle: nil).instantiateInitialViewController() as! NotificationsViewController + notificationsVC.isSidebarModeEnabled = true + + let navigationVC = UINavigationController(rootViewController: notificationsVC) + navigationVC.modalPresentationStyle = .popover + navigationVC.preferredContentSize = CGSize(width: 375, height: 800) + navigationVC.popoverPresentationController?.sourceItem = sourceItem + navigationVC.popoverPresentationController?.permittedArrowDirections = [.up] + presentingVC.present(navigationVC, animated: true) + } + required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) diff --git a/WordPress/Classes/ViewRelated/Reader/Controllers/ReaderDiscoverViewController.swift b/WordPress/Classes/ViewRelated/Reader/Controllers/ReaderDiscoverViewController.swift index 30e5e7d9d58e..29027b99b8f2 100644 --- a/WordPress/Classes/ViewRelated/Reader/Controllers/ReaderDiscoverViewController.swift +++ b/WordPress/Classes/ViewRelated/Reader/Controllers/ReaderDiscoverViewController.swift @@ -14,6 +14,8 @@ class ReaderDiscoverViewController: UIViewController, ReaderDiscoverHeaderViewDe private let tags: ManagedObjectsObserver private let viewContext: NSManagedObjectContext private var cancellables: [AnyCancellable] = [] + private let notificationsButtonViewModel = NotificationsButtonViewModel() + private var notificationsButtonCancellable: AnyCancellable? init(topic: ReaderAbstractTopic) { wpAssert(ReaderHelpers.topicIsDiscover(topic)) @@ -42,8 +44,29 @@ class ReaderDiscoverViewController: UIViewController, ReaderDiscoverHeaderViewDe showSelectInterestsIfNeeded() } + override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { + super.traitCollectionDidChange(previousTraitCollection) + + setupNotificationsBarButtonItem() + } + private func setupNavigation() { navigationItem.largeTitleDisplayMode = .never + setupNotificationsBarButtonItem() + } + + private func setupNotificationsBarButtonItem() { + notificationsButtonCancellable = nil + if traitCollection.horizontalSizeClass == .regular { + notificationsButtonCancellable = notificationsButtonViewModel.$image.sink { [weak self] in + guard let self else { return } + self.navigationItem.rightBarButtonItems = [UIBarButtonItem(image: $0, style: .plain, target: self, action: #selector(buttonShowNotificationsTapped))] + } + } + } + + @objc private func buttonShowNotificationsTapped(_ sender: UIBarButtonItem) { + NotificationsViewController.showInPopover(from: self, sourceItem: sender) } private func setupHeaderView() { diff --git a/WordPress/Classes/ViewRelated/Reader/Controllers/ReaderStreamViewController.swift b/WordPress/Classes/ViewRelated/Reader/Controllers/ReaderStreamViewController.swift index 012d87f06de9..1d5bf369672d 100644 --- a/WordPress/Classes/ViewRelated/Reader/Controllers/ReaderStreamViewController.swift +++ b/WordPress/Classes/ViewRelated/Reader/Controllers/ReaderStreamViewController.swift @@ -78,6 +78,8 @@ import AutomatticTracks private var didBumpStats = false @Lazy private var titleView = ReaderNavigationCustomTitleView() internal let scrollViewTranslationPublisher = PassthroughSubject() + private let notificationsButtonViewModel = NotificationsButtonViewModel() + private var notificationsButtonCancellable: AnyCancellable? /// Content management let content = ReaderTableContent() @@ -176,6 +178,7 @@ import AutomatticTracks private var showConfirmation = true var isEmbeddedInDiscover = false + var isNotificationsBarButtonEnabled = false var preferredTableHeaderView: UIView? var isCompact = true { @@ -350,6 +353,7 @@ import AutomatticTracks super.traitCollectionDidChange(previousTraitCollection) isCompact = traitCollection.horizontalSizeClass == .compact + setupNotificationsBarButtonItem() } private func didChangeIsCompact(_ isCompact: Bool) { @@ -357,6 +361,20 @@ import AutomatticTracks tableView.reloadData() } + private func setupNotificationsBarButtonItem() { + notificationsButtonCancellable = nil + if isNotificationsBarButtonEnabled && traitCollection.horizontalSizeClass == .regular { + notificationsButtonCancellable = notificationsButtonViewModel.$image.sink { [weak self] in + guard let self else { return } + self.navigationItem.rightBarButtonItems = [UIBarButtonItem(image: $0, style: .plain, target: self, action: #selector(buttonShowNotificationsTapped))] + } + } + } + + @objc private func buttonShowNotificationsTapped(_ sender: UIBarButtonItem) { + NotificationsViewController.showInPopover(from: self, sourceItem: sender) + } + // MARK: - Topic acquisition /// Fetches a site topic for the value of the `siteID` property.