Merge branch 'main' into ios-ui-settings-localised

This commit is contained in:
Stuart Breckenridge
2023-04-06 17:45:18 +04:00
67 changed files with 152 additions and 146 deletions

View File

@@ -246,7 +246,7 @@ public final class AccountManager: UnreadCountProvider {
}
}
public func refreshAll(errorHandler: @escaping (Error) -> Void, completion: (() -> Void)? = nil) {
public func refreshAll(errorHandler: @escaping @MainActor (Error) -> Void, completion: (() -> Void)? = nil) {
guard let reachability = try? Reachability(hostname: "apple.com"), reachability.connection != .unavailable else { return }
let group = DispatchGroup()
@@ -259,7 +259,9 @@ public final class AccountManager: UnreadCountProvider {
case .success:
break
case .failure(let error):
errorHandler(error)
Task { @MainActor in
errorHandler(error)
}
}
}
}

View File

@@ -110,7 +110,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
private var crashReporter: PLCrashReporter!
#endif
override init() {
@MainActor override init() {
NSWindow.allowsAutomaticWindowTabbing = false
super.init()
@@ -136,19 +136,19 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
}
// MARK: - API
func showAddFolderSheetOnWindow(_ window: NSWindow) {
@MainActor func showAddFolderSheetOnWindow(_ window: NSWindow) {
addFolderWindowController = AddFolderWindowController()
addFolderWindowController!.runSheetOnWindow(window)
}
func showAddWebFeedSheetOnWindow(_ window: NSWindow, urlString: String?, name: String?, account: Account?, folder: Folder?) {
@MainActor func showAddWebFeedSheetOnWindow(_ window: NSWindow, urlString: String?, name: String?, account: Account?, folder: Folder?) {
addFeedController = AddFeedController(hostWindow: window)
addFeedController?.showAddFeedSheet(.webFeed, urlString, name, account, folder)
}
// MARK: - NSApplicationDelegate
func applicationWillFinishLaunching(_ notification: Notification) {
@MainActor func applicationWillFinishLaunching(_ notification: Notification) {
installAppleEventHandlers()
CacheCleaner.purgeIfNecessary()
@@ -179,7 +179,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
appName = (Bundle.main.infoDictionary!["CFBundleExecutable"]! as! String)
}
func applicationDidFinishLaunching(_ note: Notification) {
@MainActor func applicationDidFinishLaunching(_ note: Notification) {
#if MAC_APP_STORE || TEST
checkForUpdatesMenuItem.isHidden = true
@@ -292,7 +292,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
}
func application(_ application: NSApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([NSUserActivityRestoring]) -> Void) -> Bool {
@MainActor func application(_ application: NSApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([NSUserActivityRestoring]) -> Void) -> Bool {
guard let mainWindowController = mainWindowController else {
return false
}
@@ -300,7 +300,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
return true
}
func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool {
@MainActor func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool {
// https://github.com/brentsimmons/NetNewsWire/issues/522
// I couldnt reproduce the crashing bug, but it appears to happen on creating a main window
// and its views and view controllers. The check below is so that the app does nothing
@@ -314,26 +314,26 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
return false
}
func applicationDidBecomeActive(_ notification: Notification) {
@MainActor func applicationDidBecomeActive(_ notification: Notification) {
fireOldTimers()
}
func applicationDidResignActive(_ notification: Notification) {
@MainActor func applicationDidResignActive(_ notification: Notification) {
ArticleStringFormatter.emptyCaches()
saveState()
}
func application(_ application: NSApplication, didReceiveRemoteNotification userInfo: [String : Any]) {
@MainActor func application(_ application: NSApplication, didReceiveRemoteNotification userInfo: [String : Any]) {
AccountManager.shared.receiveRemoteNotification(userInfo: userInfo)
}
func application(_ sender: NSApplication, openFile filename: String) -> Bool {
@MainActor func application(_ sender: NSApplication, openFile filename: String) -> Bool {
guard filename.hasSuffix(ArticleTheme.nnwThemeSuffix) else { return false }
importTheme(filename: filename)
return true
}
func applicationWillTerminate(_ notification: Notification) {
@MainActor func applicationWillTerminate(_ notification: Notification) {
shuttingDown = true
saveState()
@@ -347,7 +347,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
while !isShutDownSyncDone && RunLoop.current.run(mode: .default, before: timeout) && timeout > Date() { }
}
func presentThemeImportError(_ error: Error) {
@MainActor func presentThemeImportError(_ error: Error) {
var informativeText: String = ""
if let decodingError = error as? DecodingError {
@@ -386,19 +386,19 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
alert.buttons[0].keyEquivalent = "\r"
let response = alert.runModal()
_ = alert.runModal()
}
}
// MARK: Notifications
@objc func unreadCountDidChange(_ note: Notification) {
@MainActor @objc func unreadCountDidChange(_ note: Notification) {
if note.object is AccountManager {
unreadCount = AccountManager.shared.unreadCount
}
}
@objc func webFeedSettingDidChange(_ note: Notification) {
@MainActor @objc func webFeedSettingDidChange(_ note: Notification) {
guard let feed = note.object as? WebFeed, let key = note.userInfo?[WebFeed.WebFeedSettingUserInfoKey] as? String else {
return
}
@@ -407,14 +407,14 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
}
}
@objc func inspectableObjectsDidChange(_ note: Notification) {
@MainActor @objc func inspectableObjectsDidChange(_ note: Notification) {
guard let inspectorWindowController = inspectorWindowController, inspectorWindowController.isOpen else {
return
}
inspectorWindowController.objects = objectsForInspector()
}
@objc func userDefaultsDidChange(_ note: Notification) {
@MainActor @objc func userDefaultsDidChange(_ note: Notification) {
updateSortMenuItems()
updateGroupByFeedMenuItem()
@@ -426,11 +426,11 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
updateDockBadge()
}
@objc func didWakeNotification(_ note: Notification) {
@MainActor @objc func didWakeNotification(_ note: Notification) {
fireOldTimers()
}
@objc func importDownloadedTheme(_ note: Notification) {
@MainActor @objc func importDownloadedTheme(_ note: Notification) {
guard let userInfo = note.userInfo,
let url = userInfo["url"] as? URL else {
return
@@ -442,7 +442,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
// MARK: Main Window
func createMainWindowController() -> MainWindowController {
@MainActor func createMainWindowController() -> MainWindowController {
let controller: MainWindowController
controller = windowControllerWithName("MainWindow") as! MainWindowController
@@ -453,13 +453,13 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
return controller
}
func windowControllerWithName(_ storyboardName: String) -> NSWindowController {
@MainActor func windowControllerWithName(_ storyboardName: String) -> NSWindowController {
let storyboard = NSStoryboard(name: NSStoryboard.Name(storyboardName), bundle: nil)
return storyboard.instantiateInitialController()! as! NSWindowController
}
@discardableResult
func createAndShowMainWindow() -> MainWindowController {
@MainActor func createAndShowMainWindow() -> MainWindowController {
let controller = createMainWindowController()
controller.showWindow(self)
@@ -471,7 +471,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
return controller
}
func createAndShowMainWindowIfNecessary() {
@MainActor func createAndShowMainWindowIfNecessary() {
if mainWindowController == nil {
createAndShowMainWindow()
} else {
@@ -479,7 +479,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
}
}
func removeMainWindow(_ windowController: MainWindowController) {
@MainActor func removeMainWindow(_ windowController: MainWindowController) {
guard mainWindowControllers.count > 1 else { return }
if let index = mainWindowControllers.firstIndex(of: windowController) {
mainWindowControllers.remove(at: index)
@@ -487,7 +487,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
}
// MARK: NSUserInterfaceValidations
func validateUserInterfaceItem(_ item: NSValidatedUserInterfaceItem) -> Bool {
@MainActor func validateUserInterfaceItem(_ item: NSValidatedUserInterfaceItem) -> Bool {
if shuttingDown {
return false
}
@@ -533,11 +533,11 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
// MARK: UNUserNotificationCenterDelegate
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
@MainActor func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.banner, .badge, .sound])
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
@MainActor func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
@@ -553,7 +553,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
}
// MARK: Add Feed
func addWebFeed(_ urlString: String?, name: String? = nil, account: Account? = nil, folder: Folder? = nil) {
@MainActor func addWebFeed(_ urlString: String?, name: String? = nil, account: Account? = nil, folder: Folder? = nil) {
createAndShowMainWindowIfNecessary()
if mainWindowController!.isDisplayingSheet {
@@ -564,13 +564,13 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
}
// MARK: - Dock Badge
@objc func updateDockBadge() {
@MainActor @objc func updateDockBadge() {
let label = unreadCount > 0 ? "\(unreadCount)" : ""
NSApplication.shared.dockTile.badgeLabel = label
}
// MARK: - Actions
@IBAction func showPreferences(_ sender: Any?) {
@MainActor @IBAction func showPreferences(_ sender: Any?) {
if preferencesWindowController == nil {
preferencesWindowController = windowControllerWithName("Preferences")
}
@@ -578,35 +578,35 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
preferencesWindowController!.showWindow(self)
}
@IBAction func newMainWindow(_ sender: Any?) {
@MainActor @IBAction func newMainWindow(_ sender: Any?) {
createAndShowMainWindow()
}
@IBAction func showMainWindow(_ sender: Any?) {
@MainActor @IBAction func showMainWindow(_ sender: Any?) {
createAndShowMainWindowIfNecessary()
mainWindowController?.window?.makeKey()
}
@IBAction func refreshAll(_ sender: Any?) {
@MainActor @IBAction func refreshAll(_ sender: Any?) {
AccountManager.shared.refreshAll(errorHandler: ErrorHandler.present)
}
@IBAction func showAddWebFeedWindow(_ sender: Any?) {
@MainActor @IBAction func showAddWebFeedWindow(_ sender: Any?) {
addWebFeed(nil)
}
@IBAction func showAddRedditFeedWindow(_ sender: Any?) {
@MainActor @IBAction func showAddRedditFeedWindow(_ sender: Any?) {
createAndShowMainWindowIfNecessary()
addFeedController = AddFeedController(hostWindow: mainWindowController!.window!)
addFeedController?.showAddFeedSheet(.redditFeed)
}
@IBAction func showAddFolderWindow(_ sender: Any?) {
@MainActor @IBAction func showAddFolderWindow(_ sender: Any?) {
createAndShowMainWindowIfNecessary()
showAddFolderSheetOnWindow(mainWindowController!.window!)
}
@IBAction func showKeyboardShortcutsWindow(_ sender: Any?) {
@MainActor @IBAction func showKeyboardShortcutsWindow(_ sender: Any?) {
if keyboardShortcutsWindowController == nil {
keyboardShortcutsWindowController = WebViewWindowController(title: NSLocalizedString("Keyboard Shortcuts", comment: "window title"))
@@ -625,7 +625,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
keyboardShortcutsWindowController!.showWindow(self)
}
@IBAction func toggleInspectorWindow(_ sender: Any?) {
@MainActor @IBAction func toggleInspectorWindow(_ sender: Any?) {
if inspectorWindowController == nil {
inspectorWindowController = (windowControllerWithName("Inspector") as! InspectorWindowController)
}
@@ -639,7 +639,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
}
}
@IBAction func importOPMLFromFile(_ sender: Any?) {
@MainActor @IBAction func importOPMLFromFile(_ sender: Any?) {
createAndShowMainWindowIfNecessary()
if mainWindowController!.isDisplayingSheet {
return
@@ -649,7 +649,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
importOPMLController?.runSheetOnWindow(mainWindowController!.window!)
}
@IBAction func importNNW3FromFile(_ sender: Any?) {
@MainActor @IBAction func importNNW3FromFile(_ sender: Any?) {
createAndShowMainWindowIfNecessary()
if mainWindowController!.isDisplayingSheet {
return
@@ -657,7 +657,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
NNW3ImportController.askUserToImportNNW3Subscriptions(window: mainWindowController!.window!)
}
@IBAction func exportOPML(_ sender: Any?) {
@MainActor @IBAction func exportOPML(_ sender: Any?) {
createAndShowMainWindowIfNecessary()
if mainWindowController!.isDisplayingSheet {
return
@@ -667,30 +667,30 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
exportOPMLController?.runSheetOnWindow(mainWindowController!.window!)
}
@IBAction func addAppNews(_ sender: Any?) {
@MainActor @IBAction func addAppNews(_ sender: Any?) {
if AccountManager.shared.anyAccountHasNetNewsWireNewsSubscription() {
return
}
addWebFeed(AccountManager.netNewsWireNewsURL, name: "NetNewsWire News")
}
@IBAction func openWebsite(_ sender: Any?) {
@MainActor @IBAction func openWebsite(_ sender: Any?) {
Browser.open("https://netnewswire.com/", inBackground: false)
}
@IBAction func showHelp(_ sender: Any?) {
@MainActor @IBAction func showHelp(_ sender: Any?) {
Browser.open("https://netnewswire.com/help/mac/6.1/en/", inBackground: false)
}
@IBAction func gotoToday(_ sender: Any?) {
@MainActor @IBAction func gotoToday(_ sender: Any?) {
createAndShowMainWindowIfNecessary()
mainWindowController!.gotoToday(sender)
}
@IBAction func gotoAllUnread(_ sender: Any?) {
@MainActor @IBAction func gotoAllUnread(_ sender: Any?) {
createAndShowMainWindowIfNecessary()
mainWindowController!.gotoAllUnread(sender)
@@ -702,27 +702,27 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
mainWindowController!.gotoStarred(sender)
}
@IBAction func sortByOldestArticleOnTop(_ sender: Any?) {
@MainActor @IBAction func sortByOldestArticleOnTop(_ sender: Any?) {
AppDefaults.shared.timelineSortDirection = .orderedAscending
}
@IBAction func sortByNewestArticleOnTop(_ sender: Any?) {
@MainActor @IBAction func sortByNewestArticleOnTop(_ sender: Any?) {
AppDefaults.shared.timelineSortDirection = .orderedDescending
}
@IBAction func groupByFeedToggled(_ sender: NSMenuItem) {
@MainActor @IBAction func groupByFeedToggled(_ sender: NSMenuItem) {
AppDefaults.shared.timelineGroupByFeed.toggle()
}
@IBAction func checkForUpdates(_ sender: Any?) {
@MainActor @IBAction func checkForUpdates(_ sender: Any?) {
#if !MAC_APP_STORE && !TEST
self.softwareUpdater.checkForUpdates()
#endif
}
@IBAction func showAbout(_ sender: Any?) {
@MainActor @IBAction func showAbout(_ sender: Any?) {
if #available(macOS 12, *) {
for window in NSApplication.shared.windows {
if window.identifier == .aboutNetNewsWire {
@@ -741,7 +741,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
// MARK: - NSMenuDelegate
extension AppDelegate: NSMenuDelegate {
@MainActor extension AppDelegate: NSMenuDelegate {
public func menuNeedsUpdate(_ menu: NSMenu) {
let newShareMenu = mainWindowController?.shareMenu
@@ -760,7 +760,7 @@ extension AppDelegate: NSMenuDelegate {
}
// MARK: - Debug Menu
extension AppDelegate {
@MainActor extension AppDelegate {
@IBAction func debugSearch(_ sender: Any?) {
AccountManager.shared.defaultAccount.debugRunSearch()
@@ -832,7 +832,7 @@ extension AppDelegate {
}
internal extension AppDelegate {
@MainActor internal extension AppDelegate {
func fireOldTimers() {
// Its possible theres a refresh timer set to go off in the past.
@@ -1007,7 +1007,7 @@ extension AppDelegate : ScriptingAppDelegate {
}
}
extension AppDelegate: NSWindowRestoration {
@MainActor extension AppDelegate: NSWindowRestoration {
@objc static func restoreWindow(withIdentifier identifier: NSUserInterfaceItemIdentifier, state: NSCoder, completionHandler: @escaping (NSWindow?, Error?) -> Void) {
var mainWindow: NSWindow? = nil
@@ -1021,7 +1021,7 @@ extension AppDelegate: NSWindowRestoration {
// Handle Notification Actions
private extension AppDelegate {
@MainActor private extension AppDelegate {
func handleMarkAsRead(userInfo: [AnyHashable: Any]) {
markArticle(userInfo: userInfo, statusKey: .read)

View File

@@ -527,16 +527,16 @@
<autoresizingMask key="autoresizingMask"/>
<subviews>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="7UM-iq-OLB" customClass="PreferencesTableViewBackgroundView" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="44" width="180" height="219"/>
<rect key="frame" x="20" y="44" width="180" height="217"/>
<subviews>
<scrollView borderType="none" autohidesScrollers="YES" horizontalLineScroll="26" horizontalPageScroll="10" verticalLineScroll="26" verticalPageScroll="10" hasHorizontalScroller="NO" horizontalScrollElasticity="none" translatesAutoresizingMaskIntoConstraints="NO" id="PaF-du-r3c">
<rect key="frame" x="1" y="1" width="178" height="217"/>
<rect key="frame" x="1" y="1" width="178" height="215"/>
<clipView key="contentView" id="cil-Gq-akO">
<rect key="frame" x="0.0" y="0.0" width="178" height="217"/>
<rect key="frame" x="0.0" y="0.0" width="178" height="215"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" tableStyle="fullWidth" columnReordering="NO" columnSelection="YES" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="24" viewBased="YES" id="aTp-KR-y6b">
<rect key="frame" x="0.0" y="0.0" width="178" height="217"/>
<rect key="frame" x="0.0" y="0.0" width="178" height="215"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
@@ -643,7 +643,7 @@
<rect key="frame" x="83" y="20" width="117" height="24"/>
</customView>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="Y7D-xQ-wep">
<rect key="frame" x="208" y="20" width="222" height="243"/>
<rect key="frame" x="208" y="20" width="222" height="241"/>
</customView>
</subviews>
<constraints>
@@ -698,16 +698,16 @@
<autoresizingMask key="autoresizingMask"/>
<subviews>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="pjs-G4-byk" customClass="PreferencesTableViewBackgroundView" customModule="NetNewsWire" customModuleProvider="target">
<rect key="frame" x="20" y="44" width="180" height="219"/>
<rect key="frame" x="20" y="44" width="180" height="217"/>
<subviews>
<scrollView borderType="none" autohidesScrollers="YES" horizontalLineScroll="26" horizontalPageScroll="10" verticalLineScroll="26" verticalPageScroll="10" hasHorizontalScroller="NO" horizontalScrollElasticity="none" translatesAutoresizingMaskIntoConstraints="NO" id="29T-r2-ckC">
<rect key="frame" x="1" y="1" width="178" height="217"/>
<rect key="frame" x="1" y="1" width="178" height="215"/>
<clipView key="contentView" id="dXw-GY-TP8">
<rect key="frame" x="0.0" y="0.0" width="178" height="217"/>
<rect key="frame" x="0.0" y="0.0" width="178" height="215"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" tableStyle="fullWidth" columnReordering="NO" columnSelection="YES" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="24" viewBased="YES" id="dfn-Vn-oDp">
<rect key="frame" x="0.0" y="0.0" width="178" height="217"/>
<rect key="frame" x="0.0" y="0.0" width="178" height="215"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
@@ -810,7 +810,7 @@
<rect key="frame" x="83" y="20" width="117" height="24"/>
</customView>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="N1N-pE-gBL">
<rect key="frame" x="208" y="20" width="222" height="243"/>
<rect key="frame" x="208" y="20" width="222" height="241"/>
</customView>
</subviews>
<constraints>

View File

@@ -9,7 +9,7 @@
import Foundation
import RSWeb
struct Browser {
@MainActor struct Browser {
/// The user-specified default browser for opening web pages.
///

View File

@@ -8,7 +8,7 @@
import AppKit
final class CrashReportWindowController: NSWindowController {
@MainActor final class CrashReportWindowController: NSWindowController {
@IBOutlet var textView: NSTextView! {
didSet {

View File

@@ -16,7 +16,7 @@ import CrashReporter
// At some point this code should probably move into RSCore, so Rainier and any other
// future apps can use it.
struct CrashReporter {
@MainActor struct CrashReporter {
struct DefaultsKey {
static let sendCrashLogsAutomaticallyKey = "SendCrashLogsAutomatically"

View File

@@ -10,16 +10,13 @@ import AppKit
import Account
import RSCore
struct ErrorHandler: Logging {
@MainActor struct ErrorHandler: Logging {
public static func present(_ error: Error) {
NSApplication.shared.presentError(error)
}
public static func log(_ error: Error) {
ErrorHandler.logger.error("\(error.localizedDescription, privacy: .public)")
}
}

View File

@@ -66,7 +66,9 @@ struct CreditsNetNewsWireView: View, LoadableAboutData {
.onTapGesture {
guard let url = appCredit.url else { return }
if let _ = URL(string: url) {
Browser.open(url, inBackground: false)
Task { @MainActor in
Browser.open(url, inBackground: false)
}
}
}
}

View File

@@ -22,7 +22,7 @@ import RSParser
// Else,
// display error sheet.
class AddFeedController: AddFeedWindowControllerDelegate {
@MainActor final class AddFeedController: AddFeedWindowControllerDelegate {
private let hostWindow: NSWindow
private var addFeedWindowController: AddFeedWindowController?

View File

@@ -14,7 +14,7 @@ enum AddFeedWindowControllerType {
case redditFeed
}
protocol AddFeedWindowControllerDelegate: AnyObject {
@MainActor protocol AddFeedWindowControllerDelegate: AnyObject {
// userEnteredURL will have already been validated and normalized.
func addFeedWindowController(_: AddFeedWindowController, userEnteredURL: URL, userEnteredTitle: String?, container: Container)
@@ -22,7 +22,7 @@ protocol AddFeedWindowControllerDelegate: AnyObject {
}
protocol AddFeedWindowController {
@MainActor protocol AddFeedWindowController {
var window: NSWindow? { get }
func runSheetOnWindow(_ hostWindow: NSWindow)

View File

@@ -12,7 +12,7 @@ import RSTree
import Articles
import Account
class AddWebFeedWindowController : NSWindowController, AddFeedWindowController {
@MainActor final class AddWebFeedWindowController : NSWindowController, AddFeedWindowController {
@IBOutlet var urlTextField: NSTextField!
@IBOutlet var nameTextField: NSTextField!

View File

@@ -11,7 +11,7 @@ import RSCore
import RSTree
import Account
class FolderTreeMenu {
@MainActor final class FolderTreeMenu {
static func createFolderPopupMenu(with rootNode: Node, restrictToSpecialAccounts: Bool = false) -> NSMenu {

View File

@@ -10,7 +10,7 @@ import AppKit
import Articles
import Account
class AddFolderWindowController : NSWindowController {
@MainActor final class AddFolderWindowController : NSWindowController {
@IBOutlet var folderNameTextField: NSTextField!
@IBOutlet var accountPopupButton: NSPopUpButton!

View File

@@ -12,7 +12,7 @@ import RSTree
import Articles
import Account
class AddRedditFeedWindowController : NSWindowController, AddFeedWindowController {
@MainActor final class AddRedditFeedWindowController : NSWindowController, AddFeedWindowController {
@IBOutlet weak var typePopupButton: NSPopUpButton!
@IBOutlet weak var typeDescriptionLabel: NSTextField!

View File

@@ -15,7 +15,7 @@ enum ArticleExtractorButtonState {
case off
}
class ArticleExtractorButton: NSButton {
@MainActor final class ArticleExtractorButton: NSButton {
public var rightClickAction: Selector?

View File

@@ -10,7 +10,7 @@ import Foundation
import WebKit
import Articles
class DetailIconSchemeHandler: NSObject, WKURLSchemeHandler {
final class DetailIconSchemeHandler: NSObject, WKURLSchemeHandler {
var currentArticle: Article?

View File

@@ -9,7 +9,7 @@
import AppKit
import Articles
final class DetailStatusBarView: NSView {
@MainActor final class DetailStatusBarView: NSView {
@IBOutlet var urlLabel: NSTextField!

View File

@@ -20,7 +20,7 @@ enum DetailState: Equatable {
case extracted(Article, ExtractedArticle, CGFloat?)
}
final class DetailViewController: NSViewController, WKUIDelegate {
@MainActor final class DetailViewController: NSViewController, WKUIDelegate {
@IBOutlet var containerView: DetailContainerView!
@IBOutlet var statusBarView: DetailStatusBarView!

View File

@@ -10,7 +10,7 @@ import AppKit
import WebKit
import RSCore
final class DetailWebView: WKWebView {
@MainActor final class DetailWebView: WKWebView {
weak var keyboardDelegate: KeyboardDelegate?

View File

@@ -17,7 +17,7 @@ protocol DetailWebViewControllerDelegate: AnyObject {
func mouseDidExit(_: DetailWebViewController)
}
final class DetailWebViewController: NSViewController {
@MainActor final class DetailWebViewController: NSViewController {
weak var delegate: DetailWebViewControllerDelegate?
var webView: DetailWebView!

View File

@@ -8,7 +8,7 @@
import Foundation
class MainWindow: NSWindow {
@MainActor class MainWindow: NSWindow {
override func sendEvent(_ event: NSEvent) {

View File

@@ -16,7 +16,7 @@ enum TimelineSourceMode {
case regular, search
}
class MainWindowController : NSWindowController, NSUserInterfaceValidations {
@MainActor final class MainWindowController : NSWindowController, NSUserInterfaceValidations {
@IBOutlet weak var articleThemePopUpButton: NSPopUpButton?

View File

@@ -9,7 +9,7 @@
import AppKit
import Account
struct NNW3ImportController {
@MainActor struct NNW3ImportController {
/// Import NNW3 subscriptions if they exist.
/// Return true if Subscriptions.plist was found and subscriptions were imported.

View File

@@ -9,7 +9,7 @@
import AppKit
import Account
final class NNW3OpenPanelAccessoryViewController: NSViewController {
@MainActor final class NNW3OpenPanelAccessoryViewController: NSViewController {
@IBOutlet weak var accountPopUpButton: NSPopUpButton!

View File

@@ -9,7 +9,7 @@
import AppKit
import Account
class ExportOPMLWindowController: NSWindowController {
@MainActor final class ExportOPMLWindowController: NSWindowController {
@IBOutlet weak var accountPopUpButton: NSPopUpButton!
private weak var hostWindow: NSWindow?

View File

@@ -9,7 +9,7 @@
import AppKit
import Account
class ImportOPMLWindowController: NSWindowController {
@MainActor final class ImportOPMLWindowController: NSWindowController {
@IBOutlet weak var accountPopUpButton: NSPopUpButton!
private weak var hostWindow: NSWindow?

View File

@@ -11,7 +11,7 @@ import RSCore
import Account
import RSTree
class SidebarCell : NSTableCellView {
@MainActor final class SidebarCell : NSTableCellView {
var iconImage: IconImage? {
didSet {

View File

@@ -8,7 +8,7 @@
import AppKit
struct SidebarCellAppearance: Equatable {
@MainActor struct SidebarCellAppearance: Equatable {
let imageSize: CGSize
let imageMarginRight: CGFloat = 4.0

View File

@@ -11,7 +11,7 @@ import RSCore
// image - title - unreadCount
struct SidebarCellLayout {
@MainActor struct SidebarCellLayout {
let faviconRect: CGRect
let titleRect: CGRect

View File

@@ -13,7 +13,7 @@ protocol RenameWindowControllerDelegate {
func renameWindowController(_ windowController: RenameWindowController, didRenameObject: Any, withNewName: String)
}
final class RenameWindowController: NSWindowController {
@MainActor final class RenameWindowController: NSWindowController {
@IBOutlet var renamePrompt: NSTextField!
@IBOutlet var newTitleTextField: NSTextField!

View File

@@ -10,7 +10,7 @@ import AppKit
import RSTree
import Account
enum SidebarDeleteItemsAlert {
@MainActor enum SidebarDeleteItemsAlert {
/// Builds a delete confirmation dialog for the supplied nodes
static func build(_ nodes: [Node]) -> NSAlert {

View File

@@ -492,7 +492,7 @@ private extension SidebarOutlineDataSource {
return true
}
func acceptSingleNonLocalFeedDrop(_ outlineView: NSOutlineView, _ draggedFeed: PasteboardWebFeed, _ parentNode: Node, _ index: Int) -> Bool {
@MainActor func acceptSingleNonLocalFeedDrop(_ outlineView: NSOutlineView, _ draggedFeed: PasteboardWebFeed, _ parentNode: Node, _ index: Int) -> Bool {
guard nodeIsDropTarget(parentNode), index == NSOutlineViewDropOnItemIndex else {
return false
}

View File

@@ -10,7 +10,7 @@ import AppKit
import RSCore
import RSTree
class SidebarOutlineView : NSOutlineView {
@MainActor class SidebarOutlineView : NSOutlineView {
@IBOutlet var keyboardDelegate: KeyboardDelegate!

View File

@@ -12,7 +12,7 @@ import Articles
import RSWeb
import Account
final class SidebarStatusBarView: NSView {
@MainActor final class SidebarStatusBarView: NSView {
@IBOutlet var progressIndicator: NSProgressIndicator!
@IBOutlet var progressLabel: NSTextField!

View File

@@ -8,7 +8,7 @@
import AppKit
final class TimelineContainerView: NSView {
@MainActor final class TimelineContainerView: NSView {
private var contentViewConstraints: [NSLayoutConstraint]?

View File

@@ -17,7 +17,7 @@ protocol TimelineContainerViewControllerDelegate: AnyObject {
}
final class TimelineContainerViewController: NSViewController {
@MainActor final class TimelineContainerViewController: NSViewController {
@IBOutlet weak var viewOptionsPopUpButton: NSPopUpButton!
@IBOutlet weak var newestToOldestMenuItem: NSMenuItem!

View File

@@ -8,7 +8,7 @@
import AppKit
class TimelineTableRowView : NSTableRowView {
@MainActor final class TimelineTableRowView : NSTableRowView {
private var separator: NSView?

View File

@@ -9,7 +9,7 @@
import AppKit
import RSCore
class TimelineTableView: NSTableView {
@MainActor final class TimelineTableView: NSTableView {
weak var keyboardDelegate: KeyboardDelegate?

View File

@@ -8,7 +8,7 @@
import RSCore
extension URLPasteboardWriter {
@MainActor extension URLPasteboardWriter {
/// Copy URL strings, alerting the user the first time the array of URL strings contains `nil`.
/// - Parameters:

View File

@@ -8,7 +8,7 @@
import AppKit
class AccountCell: NSTableCellView {
@MainActor class AccountCell: NSTableCellView {
private var originalImage: NSImage?

View File

@@ -17,7 +17,7 @@ enum AccountsAddCloudKitWindowControllerError: LocalizedError {
}
}
class AccountsAddCloudKitWindowController: NSWindowController {
@MainActor class AccountsAddCloudKitWindowController: NSWindowController {
@IBOutlet weak var limitationsAndSolutionsTextField: NSTextField!

View File

@@ -9,7 +9,7 @@
import AppKit
import Account
class AccountsAddLocalWindowController: NSWindowController {
@MainActor class AccountsAddLocalWindowController: NSWindowController {
@IBOutlet private weak var nameTextField: NSTextField!
@IBOutlet private weak var localAccountNameTextField: NSTextField!

View File

@@ -9,7 +9,7 @@
import AppKit
import Account
final class AccountsDetailViewController: NSViewController, NSTextFieldDelegate {
@MainActor final class AccountsDetailViewController: NSViewController, NSTextFieldDelegate {
@IBOutlet weak var typeLabel: NSTextField!
@IBOutlet weak var nameTextField: NSTextField!

View File

@@ -12,7 +12,7 @@ import RSCore
import RSWeb
import Secrets
class AccountsFeedbinWindowController: NSWindowController, Logging {
@MainActor class AccountsFeedbinWindowController: NSWindowController, Logging {
@IBOutlet weak var signInTextField: NSTextField!
@IBOutlet weak var noAccountTextField: NSTextField!

View File

@@ -12,7 +12,7 @@ import RSWeb
import RSCore
import Secrets
class AccountsNewsBlurWindowController: NSWindowController, Logging {
@MainActor class AccountsNewsBlurWindowController: NSWindowController, Logging {
@IBOutlet weak var signInTextField: NSTextField!
@IBOutlet weak var noAccountTextField: NSTextField!

View File

@@ -17,7 +17,7 @@ protocol AccountsPreferencesAddAccountDelegate {
}
// MARK: - AccountsPreferencesViewController
final class AccountsPreferencesViewController: NSViewController {
@MainActor final class AccountsPreferencesViewController: NSViewController {
@IBOutlet weak var tableView: NSTableView!
@IBOutlet weak var detailView: NSView!

View File

@@ -12,7 +12,7 @@ import RSWeb
import RSCore
import Secrets
class AccountsReaderAPIWindowController: NSWindowController, Logging {
@MainActor class AccountsReaderAPIWindowController: NSWindowController, Logging {
@IBOutlet weak var titleImageView: NSImageView!
@IBOutlet weak var titleLabel: NSTextField!

View File

@@ -8,11 +8,10 @@
import AppKit
final class AdvancedPreferencesViewController: NSViewController {
@MainActor final class AdvancedPreferencesViewController: NSViewController {
@IBOutlet var releaseBuildsButton: NSButton!
@IBOutlet var testBuildsButton: NSButton!
@IBOutlet weak var privacyPolicyTextField: NSTextField!
let releaseBuildsURL = Bundle.main.infoDictionary!["SUFeedURL"]! as! String
let testBuildsURL = Bundle.main.infoDictionary!["FeedURLForTestBuilds"]! as! String
@@ -35,7 +34,6 @@ final class AdvancedPreferencesViewController: NSViewController {
NotificationCenter.default.addObserver(self, selector: #selector(userDefaultsDidChange(_:)), name: UserDefaults.didChangeNotification, object: nil)
didRegisterForNotification = true
}
privacyPolicyTextField.attributedStringValue = AppAssets.privacyPolicyLink
}
@IBAction func updateTypeButtonClicked(_ sender: Any?) {

View File

@@ -8,7 +8,7 @@
import Cocoa
class ExtensionPointDetailViewController: NSViewController {
@MainActor class ExtensionPointDetailViewController: NSViewController {
@IBOutlet weak var imageView: NSImageView!
@IBOutlet weak var titleLabel: NSTextField!

View File

@@ -11,7 +11,7 @@ import AuthenticationServices
import OAuthSwift
import Secrets
class ExtensionPointEnableWindowController: NSWindowController {
@MainActor class ExtensionPointEnableWindowController: NSWindowController {
@IBOutlet weak var imageView: NSImageView!
@IBOutlet weak var titleLabel: NSTextField!

View File

@@ -16,7 +16,7 @@ protocol ExtensionPointPreferencesEnabler: AnyObject {
func enable(_ extensionPointType: ExtensionPoint.Type)
}
final class ExtensionPointPreferencesViewController: NSViewController {
@MainActor final class ExtensionPointPreferencesViewController: NSViewController {
@IBOutlet weak var tableView: NSTableView!
@IBOutlet weak var detailView: NSView!

View File

@@ -11,7 +11,7 @@ import RSCore
import RSWeb
import UserNotifications
final class GeneralPreferencesViewController: NSViewController {
@MainActor final class GeneralPreferencesViewController: NSViewController {
private var userNotificationSettings: UNNotificationSettings?

View File

@@ -9,7 +9,7 @@
import AppKit
import RSCore
final class PreferencesControlsBackgroundView: NSView {
@MainActor final class PreferencesControlsBackgroundView: NSView {
private let lightModeFillColor = NSColor(white: 0.97, alpha: 1.0)
private let darkModeFillColor = NSColor(red: 0.32, green: 0.34, blue: 0.35, alpha: 1.0)

View File

@@ -8,7 +8,7 @@
import AppKit
final class PreferencesTableViewBackgroundView: NSView {
@MainActor final class PreferencesTableViewBackgroundView: NSView {
let lightBorderColor = NSColor(white: 0.71, alpha: 1.0)
let darkBorderColor = NSColor(red: 0.41, green: 0.43, blue: 0.44, alpha: 1.0)

View File

@@ -28,7 +28,7 @@ private struct ToolbarItemIdentifier {
static let Advanced = "Advanced"
}
class PreferencesWindowController : NSWindowController, NSToolbarDelegate {
@MainActor class PreferencesWindowController : NSWindowController, NSToolbarDelegate {
private let windowWidth = CGFloat(512.0) // Width is constant for all views; only the height changes
private var viewControllers = [String: NSViewController]()

View File

@@ -62,7 +62,7 @@
<key>NSAppleScriptEnabled</key>
<true/>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2002-2022 Brent Simmons. All rights reserved.</string>
<string>Copyright © 2002-2023 Brent Simmons. All rights reserved.</string>
<key>NSMainStoryboardFile</key>
<string>Main</string>
<key>NSPrincipalClass</key>

View File

@@ -39,7 +39,7 @@ extension AppDelegate : AppDelegateAppleEvents {
NSAppleEventManager.shared().setEventHandler(self, andSelector: #selector(AppDelegate.getURL(_:_:)), forEventClass: AEEventClass(kInternetEventClass), andEventID: AEEventID(kAEGetURL))
}
@objc func getURL(_ event: NSAppleEventDescriptor, _ withReplyEvent: NSAppleEventDescriptor) {
@MainActor @objc func getURL(_ event: NSAppleEventDescriptor, _ withReplyEvent: NSAppleEventDescriptor) {
guard var urlString = event.paramDescriptor(forKeyword: keyDirectObject)?.stringValue else {
return
@@ -63,7 +63,9 @@ extension AppDelegate : AppDelegateAppleEvents {
do {
try ArticleThemeDownloader.shared.handleFile(at: location)
} catch {
self.presentThemeImportError(error)
Task { @MainActor in
self.presentThemeImportError(error)
}
}
}
task.resume()

View File

@@ -40,10 +40,10 @@ class ArticleExtractor: Logging {
let clientURL = "https://extract.feedbin.com/parser"
let username = SecretsManager.provider.mercuryClientId
let signiture = articleLink.hmacUsingSHA1(key: SecretsManager.provider.mercuryClientSecret)
let signature = articleLink.hmacUsingSHA1(key: SecretsManager.provider.mercuryClientSecret)
if let base64URL = articleLink.data(using: .utf8)?.base64EncodedString() {
let fullURL = "\(clientURL)/\(username)/\(signiture)?base64_url=\(base64URL)"
let fullURL = "\(clientURL)/\(username)/\(signature)?base64_url=\(base64URL)"
if let url = URL(string: fullURL) {
self.url = url
return

View File

@@ -88,7 +88,9 @@ final class ArticleThemesManager: NSObject, NSFilePresenter, Logging, Observable
do {
currentTheme = try articleThemeWithThemeName(currentThemeName)
} catch {
appDelegate.presentThemeImportError(error)
Task { @MainActor in
appDelegate.presentThemeImportError(error)
}
}
}
}

View File

@@ -10,7 +10,7 @@ import Foundation
import Account
import RSCore
struct OPMLExporter {
@MainActor struct OPMLExporter {
static func OPMLString(with account: Account, title: String) -> String {

View File

@@ -10,7 +10,7 @@ import Foundation
import RSWeb
import RSCore
struct CacheCleaner: Logging {
@MainActor struct CacheCleaner: Logging {
static func purgeIfNecessary() {

View File

@@ -5,12 +5,17 @@
</head>
<body>
<outline text="BBC News - World" title="BBC News - World" type="rss" version="RSS" htmlUrl="https://www.bbc.com/news" xmlUrl="https://feeds.bbci.co.uk/news/world/rss.xml"/>
<outline text="Allen Pike" title="Allen Pike" type="rss" version="RSS" htmlUrl="https://www.allenpike.com/" xmlUrl="https://feeds.allenpike.com/feed/"/>
<outline text="Becky Hansmeyer" title="Becky Hansmeyer" type="rss" version="RSS" htmlUrl="https://beckyhansmeyer.com" xmlUrl="https://beckyhansmeyer.com/feed/"/>
<outline text="Colossal" title="Colossal" type="rss" version="RSS" htmlUrl="https://www.thisiscolossal.com/" xmlUrl="https://www.thisiscolossal.com/feed/"/>
<outline text="Craig Hockenberry" title="Craig Hockenberry" type="rss" version="RSS" htmlUrl="https://furbo.org/" xmlUrl="https://furbo.org/feed/json"/>
<outline text="Daring Fireball" title="Daring Fireball" type="rss" version="RSS" htmlUrl="https://daringfireball.net/" xmlUrl="https://daringfireball.net/feeds/json"/>
<outline text="inessential" title="inessential" type="rss" version="RSS" htmlUrl="https://inessential.com/" xmlUrl="https://inessential.com/feed.json"/>
<outline text="Jason Kottke" title="Jason Kottke" type="rss" version="RSS" htmlUrl="https://kottke.org/" xmlUrl="http://feeds.kottke.org/json"/>
<outline text="Julia Evans" title="Julia Evans" type="rss" version="RSS" htmlUrl="https://jvns.ca/" xmlUrl="https://jvns.ca/atom.xml"/>
<outline text="Manton Reece" title="Manton Reece" type="rss" version="RSS" htmlUrl="https://manton.org/" xmlUrl="https://www.manton.org/feed/json"/>
<outline text="Maurice Parker" title="Maurice Parker" type="rss" version="RSS" htmlUrl="https://vincode.io/" xmlUrl="https://vincode.io/feed.xml"/>
<outline text="Michael Tsai" title="Michael Tsai" type="rss" version="RSS" htmlUrl="https://mjtsai.com/blog/" xmlUrl="https://mjtsai.com/blog/feed/"/>
<outline text="NetNewsWire Blog" title="NetNewsWire Blog" type="rss" version="RSS" htmlUrl="https://nnw.ranchero.com/" xmlUrl="https://nnw.ranchero.com/feed.json"/>
<outline text="One Foot Tsunami" title="One Foot Tsunami" type="rss" version="RSS" htmlUrl="https://onefoottsunami.com/" xmlUrl="https://onefoottsunami.com/feed/json/"/>
<outline text="Six Colors" title="Six Colors" type="rss" version="RSS" htmlUrl="https://sixcolors.com/" xmlUrl="https://feedpress.me/sixcolors?type=xml"/>

View File

@@ -10,7 +10,7 @@ import Foundation
import Account
import RSCore
struct DefaultFeedsImporter {
@MainActor struct DefaultFeedsImporter {
static func importDefaultFeeds(account: Account) {
let defaultFeedsURL = Bundle.main.url(forResource: "DefaultFeeds", withExtension: "opml")!

View File

@@ -694,7 +694,7 @@ class MasterFeedViewController: UITableViewController, UndoableCommandRunner, Ma
private func showTwitterDeprecationAlert() {
let alert = UIAlertController(title: NSLocalizedString("Twitter Integration Removed", comment: "Twitter Integration Removed"),
message: NSLocalizedString("On February 1, 2023, Twitter announced the end of free access to the Twitter API, effective February 9.\n\nSince Twitter does not provide RSS feeds, weve had to use the Twitter API. Without free access to that API, we cant read feeds from Twitter.\n\nWeve left your Twitter feeds intact. If you have any starred items from those feeds, they will remain as long as you dont delete those feeds.\n\nYou can still read whatever you have already downloaded. However, those feeds will no longer update.", comment: "Twitter deprecation message"),
message: NSLocalizedString("Twitter has ended free access to the parts of the Twitter API that we need.\n\nSince Twitter does not provide RSS feeds, weve had to use the Twitter API. Without free access to that API, we cant read feeds from Twitter.\n\nWeve left your Twitter feeds intact. If you have any starred items from those feeds, they will remain as long as you dont delete those feeds.\n\nYou can still read whatever you have already downloaded. However, those feeds will no longer update.", comment: "Twitter deprecation message"),
preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .cancel))

View File

@@ -34,7 +34,7 @@ class MasterTimelineViewController: UITableViewController, UndoableCommandRunner
private var markAsReadOnScrollWorkItem: DispatchWorkItem?
private var markAsReadOnScrollStart: Int?
private var markAsReadOnScrollEnd: Int?
private var lastVerticlePosition: CGFloat = 0
private var lastVerticalPosition: CGFloat = 0
var mainControllerIdentifier = MainControllerIdentifier.masterTimeline
@@ -696,7 +696,7 @@ private extension MasterTimelineViewController {
}
func applyChanges(animated: Bool, completion: (() -> Void)? = nil) {
lastVerticlePosition = 0
lastVerticalPosition = 0
if coordinator.articles.count == 0 {
tableView.rowHeight = tableView.estimatedRowHeight
@@ -753,15 +753,15 @@ private extension MasterTimelineViewController {
func markAsReadOnScroll() {
// Only try to mark if we are scrolling up
defer {
lastVerticlePosition = tableView.contentOffset.y
lastVerticalPosition = tableView.contentOffset.y
}
guard lastVerticlePosition < tableView.contentOffset.y else {
guard lastVerticalPosition < tableView.contentOffset.y else {
return
}
// Implement Mark As Read on Scroll where we mark after the leading edge goes a little beyond the safe area inset
guard AppDefaults.shared.markArticlesAsReadOnScroll,
lastVerticlePosition < tableView.contentOffset.y,
lastVerticalPosition < tableView.contentOffset.y,
let firstVisibleIndexPath = tableView.indexPathsForVisibleRows?.first else { return }
let firstVisibleRowRect = tableView.rectForRow(at: firstVisibleIndexPath)

View File

@@ -29,8 +29,6 @@ class TitleActivityItemSource: NSObject, UIActivityItemSource {
switch activityType.rawValue {
case "com.omnigroup.OmniFocus3.iOS.QuickEntry",
"com.culturedcode.ThingsiPhone.ShareExtension",
"com.tapbots.Tweetbot4.shareextension",
"com.tapbots.Tweetbot6.shareextension",
"com.buffer.buffer.Buffer":
return title
default:

View File

@@ -1,7 +1,7 @@
// High Level Settings common to both the iOS application and any extensions we bundle with it
MARKETING_VERSION = 6.1.1
CURRENT_PROJECT_VERSION = 6114
CURRENT_PROJECT_VERSION = 6115
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon