From 09652bff81794ab4367c6cc07932aee6d2d6eff4 Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Wed, 29 Dec 2021 14:44:40 -0800 Subject: [PATCH] Remove Mark Read on Scroll code --- Mac/AppDefaults.swift | 11 --- ...melineViewController+ContextualMenus.swift | 3 - .../Timeline/TimelineViewController.swift | 89 ------------------- iOS/AppDefaults.swift | 11 --- .../MasterTimelineViewController.swift | 52 +---------- iOS/SceneCoordinator.swift | 10 --- 6 files changed, 1 insertion(+), 175 deletions(-) diff --git a/Mac/AppDefaults.swift b/Mac/AppDefaults.swift index 9a1ce53f0..df9b7c618 100644 --- a/Mac/AppDefaults.swift +++ b/Mac/AppDefaults.swift @@ -33,7 +33,6 @@ final class AppDefaults { static let detailFontSize = "detailFontSize" static let openInBrowserInBackground = "openInBrowserInBackground" static let subscribeToFeedsInDefaultBrowser = "subscribeToFeedsInDefaultBrowser" - static let markArticlesAsReadOnScroll = "markArticlesAsReadOnScroll" static let articleTextSize = "articleTextSize" static let refreshInterval = "refreshInterval" static let addWebFeedAccountID = "addWebFeedAccountID" @@ -290,16 +289,6 @@ final class AppDefaults { return AppDefaults.bool(for: Key.timelineShowsSeparators) } - - var markArticlesAsReadOnScroll: Bool { - get { - return AppDefaults.bool(for: Key.markArticlesAsReadOnScroll) - } - set { - AppDefaults.setBool(for: Key.markArticlesAsReadOnScroll, newValue) - } - } - var articleTextSize: ArticleTextSize { get { let rawValue = UserDefaults.standard.integer(forKey: Key.articleTextSize) diff --git a/Mac/MainWindow/Timeline/TimelineViewController+ContextualMenus.swift b/Mac/MainWindow/Timeline/TimelineViewController+ContextualMenus.swift index 42ec68d95..dd83afdcb 100644 --- a/Mac/MainWindow/Timeline/TimelineViewController+ContextualMenus.swift +++ b/Mac/MainWindow/Timeline/TimelineViewController+ContextualMenus.swift @@ -111,9 +111,6 @@ private extension TimelineViewController { func markArticles(_ articles: [Article], read: Bool) { markArticles(articles, statusKey: .read, flag: read) - for article in articles { - articlesWithManuallyChangedReadStatus.insert(article) - } } func markArticles(_ articles: [Article], starred: Bool) { diff --git a/Mac/MainWindow/Timeline/TimelineViewController.swift b/Mac/MainWindow/Timeline/TimelineViewController.swift index 3234ca050..1467649e4 100644 --- a/Mac/MainWindow/Timeline/TimelineViewController.swift +++ b/Mac/MainWindow/Timeline/TimelineViewController.swift @@ -70,7 +70,6 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner, Unr if showsSearchResults { fetchAndReplaceArticlesAsync() } else { - resetMarkAsReadOnScroll() fetchAndReplaceArticlesSync() if articles.count > 0 { tableView.scrollRowToVisible(0) @@ -140,10 +139,6 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner, Unr var undoableCommands = [UndoableCommand]() - var articlesWithManuallyChangedReadStatus: Set
= Set() - - private var isScrolling = false - private var fetchSerialNumber = 0 private let fetchRequestQueue = FetchRequestQueue() private var exceptionArticleFetcher: ArticleFetcher? @@ -197,10 +192,6 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner, Unr private let keyboardDelegate = TimelineKeyboardDelegate() private var timelineShowsSeparatorsObserver: NSKeyValueObservation? - private let scrollPositionQueue = CoalescingQueue(name: "Timeline Scroll Position", interval: 0.3, maxInterval: 1.0) - - private var markBottomArticlesAsReadWorkItem: DispatchWorkItem? - convenience init(delegate: TimelineDelegate) { self.init(nibName: "TimelineTableView", bundle: nil) self.delegate = delegate @@ -232,17 +223,6 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner, Unr NotificationCenter.default.addObserver(self, selector: #selector(accountsDidChange(_:)), name: .UserDidDeleteAccount, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(containerChildrenDidChange(_:)), name: .ChildrenDidChange, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(userDefaultsDidChange(_:)), name: UserDefaults.didChangeNotification, object: nil) - - if let scrollView = self.tableView.enclosingScrollView { - scrollView.contentView.postsBoundsChangedNotifications = true - - NotificationCenter.default.addObserver(self, selector: #selector(scrollViewDidScroll(notification:)), name: NSView.boundsDidChangeNotification, object: scrollView.contentView) - - NotificationCenter.default.addObserver(self, selector: #selector(scrollViewWillStartLiveScroll(notification:)), name: NSScrollView.willStartLiveScrollNotification, object: scrollView) - NotificationCenter.default.addObserver(self, selector: #selector(scrollViewDidEndLiveScroll(notification:)), name: NSScrollView.didEndLiveScrollNotification, object: scrollView) - - } - didRegisterForNotifications = true } } @@ -301,8 +281,6 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner, Unr } func restoreState(from state: [AnyHashable : Any]) { - resetMarkAsReadOnScroll() - guard let readArticlesFilterStateKeys = state[UserInfoKey.readArticlesFilterStateKeys] as? [[AnyHashable: AnyHashable]], let readArticlesFilterStateValues = state[UserInfoKey.readArticlesFilterStateValues] as? [Bool] else { return @@ -346,66 +324,6 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner, Unr } } - @objc func scrollViewDidScroll(notification: Notification){ - if isScrolling { - scrollPositionQueue.add(self, #selector(scrollPositionDidChange)) - } - } - - @objc func scrollViewWillStartLiveScroll(notification: Notification){ - isScrolling = true - } - - @objc func scrollViewDidEndLiveScroll(notification: Notification){ - isScrolling = false - } - - @objc func scrollPositionDidChange(){ - if !AppDefaults.shared.markArticlesAsReadOnScroll { - return - } - - // Mark all articles as read when the bottom of the feed is reached - let lastRowIndex = articles.count - 1 - let atBottom = tableView.rows(in: tableView.visibleRect).contains(lastRowIndex) - - if atBottom && markBottomArticlesAsReadWorkItem == nil { - let task = DispatchWorkItem { - let articlesToMarkAsRead = self.articles.filter { !$0.status.read && !self.articlesWithManuallyChangedReadStatus.contains($0) } - - if articlesToMarkAsRead.isEmpty { return } - guard let undoManager = self.undoManager, let markReadCommand = MarkStatusCommand(initialArticles: articlesToMarkAsRead, markingRead: true, undoManager: undoManager) else { - return - } - self.runCommand(markReadCommand) - self.markBottomArticlesAsReadWorkItem = nil - } - - markBottomArticlesAsReadWorkItem = task - DispatchQueue.main.asyncAfter(deadline: .now() + 2, execute: task) - } else if !atBottom, let task = markBottomArticlesAsReadWorkItem { - task.cancel() - markBottomArticlesAsReadWorkItem = nil - } - - - // Mark articles scrolled out of sight at the top as read - let firstVisibleRowIndex = tableView.rows(in: tableView.visibleRect).location - let unreadArticlesScrolledAway = articles.articlesAbove(position: firstVisibleRowIndex).filter { !$0.status.read && !articlesWithManuallyChangedReadStatus.contains($0) } - - if unreadArticlesScrolledAway.isEmpty { return } - - guard let undoManager = undoManager, let markReadCommand = MarkStatusCommand(initialArticles: unreadArticlesScrolledAway, markingRead: true, undoManager: undoManager) else { - return - } - runCommand(markReadCommand) - } - - func resetMarkAsReadOnScroll() { - articlesWithManuallyChangedReadStatus.removeAll() - markBottomArticlesAsReadWorkItem?.cancel() - } - @IBAction func toggleStatusOfSelectedArticles(_ sender: Any?) { guard !selectedArticles.isEmpty else { return @@ -427,9 +345,6 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner, Unr return } runCommand(markReadCommand) - for article in selectedArticles { - articlesWithManuallyChangedReadStatus.insert(article) - } } @IBAction func markSelectedArticlesAsUnread(_ sender: Any?) { @@ -437,9 +352,6 @@ final class TimelineViewController: NSViewController, UndoableCommandRunner, Unr return } runCommand(markUnreadCommand) - for article in selectedArticles { - articlesWithManuallyChangedReadStatus.insert(article) - } } @IBAction func copy(_ sender: Any?) { @@ -991,7 +903,6 @@ extension TimelineViewController: NSTableViewDelegate { return } self.runCommand(markUnreadCommand) - articlesWithManuallyChangedReadStatus.insert(article) } private func toggleArticleStarred(_ article: Article) { diff --git a/iOS/AppDefaults.swift b/iOS/AppDefaults.swift index 17ffbeb1a..c7a01f33a 100644 --- a/iOS/AppDefaults.swift +++ b/iOS/AppDefaults.swift @@ -46,7 +46,6 @@ final class AppDefaults { static let firstRunDate = "firstRunDate" static let timelineGroupByFeed = "timelineGroupByFeed" static let refreshClearsReadArticles = "refreshClearsReadArticles" - static let markArticlesAsReadOnScroll = "markArticlesAsReadOnScroll" static let timelineNumberOfLines = "timelineNumberOfLines" static let timelineIconDimension = "timelineIconSize" static let timelineSortDirection = "timelineSortDirection" @@ -160,15 +159,6 @@ final class AppDefaults { } } - var markArticlesAsReadOnScroll: Bool { - get { - return AppDefaults.bool(for: Key.markArticlesAsReadOnScroll) - } - set { - AppDefaults.setBool(for: Key.markArticlesAsReadOnScroll, newValue) - } - } - var timelineSortDirection: ComparisonResult { get { return AppDefaults.sortDirection(for: Key.timelineSortDirection) @@ -246,7 +236,6 @@ final class AppDefaults { let defaults: [String : Any] = [Key.userInterfaceColorPalette: UserInterfaceColorPalette.automatic.rawValue, Key.timelineGroupByFeed: false, Key.refreshClearsReadArticles: false, - Key.markArticlesAsReadOnScroll: false, Key.timelineNumberOfLines: 2, Key.timelineIconDimension: IconSize.medium.rawValue, Key.timelineSortDirection: ComparisonResult.orderedDescending.rawValue, diff --git a/iOS/MasterTimeline/MasterTimelineViewController.swift b/iOS/MasterTimeline/MasterTimelineViewController.swift index 808737c34..9456f369b 100644 --- a/iOS/MasterTimeline/MasterTimelineViewController.swift +++ b/iOS/MasterTimeline/MasterTimelineViewController.swift @@ -418,9 +418,7 @@ class MasterTimelineViewController: UITableViewController, UndoableCommandRunner } override func scrollViewDidScroll(_ scrollView: UIScrollView) { - if scrollView.isTracking { - scrollPositionQueue.add(self, #selector(scrollPositionDidChange)) - } + scrollPositionQueue.add(self, #selector(scrollPositionDidChange)) } // MARK: Notifications @@ -518,54 +516,6 @@ class MasterTimelineViewController: UITableViewController, UndoableCommandRunner @objc func scrollPositionDidChange() { coordinator.timelineMiddleIndexPath = tableView.middleVisibleRow() - - if !AppDefaults.shared.markArticlesAsReadOnScroll { - return - } - - // Mark all articles as read when the bottom of the feed is reached - if let lastVisibleRowIndexPath = tableView.indexPathsForVisibleRows?.last { - let atBottom = dataSource.itemIdentifier(for: lastVisibleRowIndexPath) == coordinator.articles.last - - if atBottom && coordinator.markBottomArticlesAsReadWorkItem == nil { - let task = DispatchWorkItem { - let articlesToMarkAsRead = self.coordinator.articles.filter { !$0.status.read && !self.coordinator.articlesWithManuallyChangedReadStatus.contains($0) } - - if articlesToMarkAsRead.isEmpty { return } - self.coordinator.markAllAsRead(articlesToMarkAsRead) - self.coordinator.markBottomArticlesAsReadWorkItem = nil - } - - coordinator.markBottomArticlesAsReadWorkItem = task - DispatchQueue.main.asyncAfter(deadline: .now() + 2, execute: task) - } else if !atBottom, let task = coordinator.markBottomArticlesAsReadWorkItem { - task.cancel() - coordinator.markBottomArticlesAsReadWorkItem = nil - } - } - - // Mark articles scrolled out of sight at the top as read - guard let visibleRowIndexPaths = tableView.indexPathsForVisibleRows, visibleRowIndexPaths.count > 0 else { return } - let firstVisibleRowIndexPath = visibleRowIndexPaths[0] - - guard let firstVisibleArticle = dataSource.itemIdentifier(for: firstVisibleRowIndexPath) else { - return - } - - guard let unreadArticlesScrolledAway = coordinator.articles - .articlesAbove(article: firstVisibleArticle) - .filter({ !coordinator.articlesWithManuallyChangedReadStatus.contains($0) }) - .unreadArticles() else { return } - - coordinator.markAllAsRead(unreadArticlesScrolledAway) - - for article in unreadArticlesScrolledAway { - if let indexPath = dataSource.indexPath(for: article) { - if let cell = tableView.cellForRow(at: indexPath) as? MasterTimelineTableViewCell { - configure(cell, article: article) - } - } - } } // MARK: Reloading diff --git a/iOS/SceneCoordinator.swift b/iOS/SceneCoordinator.swift index c8a7f9138..4a0b98498 100644 --- a/iOS/SceneCoordinator.swift +++ b/iOS/SceneCoordinator.swift @@ -182,9 +182,6 @@ class SceneCoordinator: NSObject, UndoableCommandRunner { private(set) var showFeedNames = ShowFeedName.none private(set) var showIcons = false - var articlesWithManuallyChangedReadStatus: Set
= Set() - var markBottomArticlesAsReadWorkItem: DispatchWorkItem? - var prevFeedIndexPath: IndexPath? { guard let indexPath = currentFeedIndexPath else { return nil @@ -786,9 +783,6 @@ class SceneCoordinator: NSObject, UndoableCommandRunner { return } - articlesWithManuallyChangedReadStatus.removeAll() - markBottomArticlesAsReadWorkItem?.cancel() - currentFeedIndexPath = indexPath masterFeedViewController.updateFeedSelection(animations: animations) @@ -1079,28 +1073,24 @@ class SceneCoordinator: NSObject, UndoableCommandRunner { func markAsReadForCurrentArticle() { if let article = currentArticle { markArticlesWithUndo([article], statusKey: .read, flag: true) - articlesWithManuallyChangedReadStatus.insert(article) } } func markAsUnreadForCurrentArticle() { if let article = currentArticle { markArticlesWithUndo([article], statusKey: .read, flag: false) - articlesWithManuallyChangedReadStatus.insert(article) } } func toggleReadForCurrentArticle() { if let article = currentArticle { toggleRead(article) - articlesWithManuallyChangedReadStatus.insert(article) } } func toggleRead(_ article: Article) { guard !article.status.read || article.isAvailableToMarkUnread else { return } markArticlesWithUndo([article], statusKey: .read, flag: !article.status.read) - articlesWithManuallyChangedReadStatus.insert(article) } func toggleStarredForCurrentArticle() {