From 8b3bbca28dace04209bc1308c676ee933d094574 Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Thu, 11 Feb 2021 15:21:53 -0600 Subject: [PATCH 01/67] Update to the latest RSCore --- .../project.xcworkspace/xcshareddata/swiftpm/Package.resolved | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NetNewsWire.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/NetNewsWire.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 0ca6b48cc..71a837402 100644 --- a/NetNewsWire.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/NetNewsWire.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -60,8 +60,8 @@ "repositoryURL": "https://github.com/Ranchero-Software/RSCore.git", "state": { "branch": null, - "revision": "55295e826ac0249ac0c271e83c4489313b350a7c", - "version": "1.0.1" + "revision": "6b2ef2580968905af825c40442dc0ba3126032c0", + "version": "1.0.2" } }, { From e36e4ac5bc0e7a826312b09c62142b128432d321 Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Sat, 13 Feb 2021 16:14:44 -0600 Subject: [PATCH 02/67] Correctly clear the progress bar for not found feeds and already subscribed feeds --- .../Sources/Account/CloudKit/CloudKitAccountDelegate.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift b/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift index e5b9bc84d..daf96d4d2 100644 --- a/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift +++ b/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift @@ -673,14 +673,14 @@ private extension CloudKitAccountDelegate { case .success(let feedSpecifiers): guard let bestFeedSpecifier = FeedSpecifier.bestFeed(in: feedSpecifiers), let url = URL(string: bestFeedSpecifier.urlString) else { BatchUpdate.shared.end() - self.refreshProgress.completeTasks(5) + self.refreshProgress.completeTasks(4) completion(.failure(AccountError.createErrorNotFound)) return } if account.hasWebFeed(withURL: bestFeedSpecifier.urlString) { BatchUpdate.shared.end() - self.refreshProgress.completeTasks(5) + self.refreshProgress.completeTasks(4) completion(.failure(AccountError.createErrorAlreadySubscribed)) return } From b47a1fac61706e325a32666c870b5cee231cac85 Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Sat, 13 Feb 2021 16:25:17 -0600 Subject: [PATCH 03/67] Correctly clear the progress bar when a feed provider isn't able to find a feed --- Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift b/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift index daf96d4d2..160c5e8c9 100644 --- a/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift +++ b/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift @@ -657,7 +657,7 @@ private extension CloudKitAccountDelegate { } case .failure: - self.refreshProgress.completeTasks(5) + self.refreshProgress.completeTasks(4) completion(.failure(AccountError.createErrorNotFound)) } } From 649e3e86ef0f55e16652198557b765a7d0559ce0 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sun, 21 Feb 2021 18:00:40 -0800 Subject: [PATCH 04/67] Update URLs to use netnewswire.com where appropriate. --- Mac/AppDelegate.swift | 8 ++++---- Mac/CrashReporter/CrashReporter.swift | 2 +- Mac/Resources/Info.plist | 2 +- Multiplatform/iOS/Info.plist | 2 +- Multiplatform/iOS/SafariView.swift | 2 +- Multiplatform/iOS/Settings/About/About.rtf | 4 ++-- Multiplatform/iOS/Settings/SettingsModel.swift | 6 +++--- Multiplatform/macOS/Info.plist | 2 +- .../Advanced/AdvancedPreferencesView.swift | 2 +- README.md | 4 ++-- Shared/ArticleStyles/ArticleStyle.swift | 2 +- iOS/Resources/About.rtf | 6 +++--- iOS/Resources/Info.plist | 2 +- iOS/Settings/SettingsViewController.swift | 6 +++--- 14 files changed, 25 insertions(+), 25 deletions(-) diff --git a/Mac/AppDelegate.swift b/Mac/AppDelegate.swift index 23b5e819c..52b0abd0f 100644 --- a/Mac/AppDelegate.swift +++ b/Mac/AppDelegate.swift @@ -608,7 +608,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations, @IBAction func openWebsite(_ sender: Any?) { - Browser.open("https://ranchero.com/netnewswire/", inBackground: false) + Browser.open("https://netnewswire.com/", inBackground: false) } @IBAction func openReleaseNotes(_ sender: Any?) { @@ -632,7 +632,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations, } @IBAction func openSlackGroup(_ sender: Any?) { - Browser.open("https://ranchero.com/netnewswire/slack", inBackground: false) + Browser.open("https://netnewswire.com/slack", inBackground: false) } @IBAction func openTechnotes(_ sender: Any?) { @@ -642,7 +642,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations, @IBAction func showHelp(_ sender: Any?) { - Browser.open("https://ranchero.com/netnewswire/help/mac/5.1/en/", inBackground: false) + Browser.open("https://netnewswire.com/help/mac/5.1/en/", inBackground: false) } @IBAction func donateToAppCampForGirls(_ sender: Any?) { @@ -650,7 +650,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations, } @IBAction func showPrivacyPolicy(_ sender: Any?) { - Browser.open("https://ranchero.com/netnewswire/privacypolicy", inBackground: false) + Browser.open("https://netnewswire.com/privacypolicy", inBackground: false) } @IBAction func gotoToday(_ sender: Any?) { diff --git a/Mac/CrashReporter/CrashReporter.swift b/Mac/CrashReporter/CrashReporter.swift index 06aa3f5e6..9c15e602e 100644 --- a/Mac/CrashReporter/CrashReporter.swift +++ b/Mac/CrashReporter/CrashReporter.swift @@ -42,7 +42,7 @@ struct CrashReporter { } static func sendCrashLogText(_ crashLogText: String) { - var request = URLRequest(url: URL(string: "https://ranchero.com/netnewswire/crashreportcatcher.php")!) + var request = URLRequest(url: URL(string: "https://netnewswire.com/crashreportcatcher.php")!) request.httpMethod = HTTPMethod.post let boundary = "0xKhTmLbOuNdArY" diff --git a/Mac/Resources/Info.plist b/Mac/Resources/Info.plist index e2b17681d..f095490dd 100644 --- a/Mac/Resources/Info.plist +++ b/Mac/Resources/Info.plist @@ -72,6 +72,6 @@ SUFeedURL https://ranchero.com/downloads/netnewswire-release.xml UserAgent - NetNewsWire (RSS Reader; https://ranchero.com/netnewswire/) + NetNewsWire (RSS Reader; https://netnewswire.com/) diff --git a/Multiplatform/iOS/Info.plist b/Multiplatform/iOS/Info.plist index cab22bf05..5be8136b3 100644 --- a/Multiplatform/iOS/Info.plist +++ b/Multiplatform/iOS/Info.plist @@ -72,7 +72,7 @@ remote-notification UserAgent - NetNewsWire (RSS Reader; https://ranchero.com/netnewswire/) + NetNewsWire (RSS Reader; https://netnewswire.com/) OrganizationIdentifier $(ORGANIZATION_IDENTIFIER) DeveloperEntitlements diff --git a/Multiplatform/iOS/SafariView.swift b/Multiplatform/iOS/SafariView.swift index b3a96e718..62f1bc36c 100644 --- a/Multiplatform/iOS/SafariView.swift +++ b/Multiplatform/iOS/SafariView.swift @@ -58,6 +58,6 @@ struct SafariView: View { struct SafariView_Previews: PreviewProvider { static var previews: some View { - SafariView(url: URL(string: "https://ranchero.com/netnewswire/")!) + SafariView(url: URL(string: "https://netnewswire.com/")!) } } diff --git a/Multiplatform/iOS/Settings/About/About.rtf b/Multiplatform/iOS/Settings/About/About.rtf index 41b356e05..b8aa6f4e5 100644 --- a/Multiplatform/iOS/Settings/About/About.rtf +++ b/Multiplatform/iOS/Settings/About/About.rtf @@ -1,4 +1,4 @@ -{\rtf1\ansi\ansicpg1252\cocoartf2511 +{\rtf1\ansi\ansicpg1252\cocoartf2513 \cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset0 LucidaGrande-Bold;} {\colortbl;\red255\green255\blue255;\red0\green0\blue0;\red10\green96\blue255;} {\*\expandedcolortbl;;\cssrgb\c0\c0\c0;\cssrgb\c0\c47843\c100000\cname systemBlueColor;} @@ -9,4 +9,4 @@ \fs22 \ \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 {\field{\*\fldinst{HYPERLINK "https://ranchero.com/netnewswire/"}}{\fldrslt -\fs28 \cf3 ranchero.com/netnewswire/}}} \ No newline at end of file +\fs28 \cf3 netnewswire.com}}} \ No newline at end of file diff --git a/Multiplatform/iOS/Settings/SettingsModel.swift b/Multiplatform/iOS/Settings/SettingsModel.swift index 63443d3fc..3c8218ae1 100644 --- a/Multiplatform/iOS/Settings/SettingsModel.swift +++ b/Multiplatform/iOS/Settings/SettingsModel.swift @@ -17,9 +17,9 @@ class SettingsModel: ObservableObject { var url: URL? { switch self { case .netNewsWireHelp: - return URL(string: "https://ranchero.com/netnewswire/help/ios/5.0/en/")! + return URL(string: "https://netnewswire.com/help/ios/5.0/en/")! case .netNewsWire: - return URL(string: "https://ranchero.com/netnewswire/")! + return URL(string: "https://netnewswire.com/")! case .supportNetNewsWire: return URL(string: "https://github.com/brentsimmons/NetNewsWire/blob/main/Technotes/HowToSupportNetNewsWire.markdown")! case .github: @@ -29,7 +29,7 @@ class SettingsModel: ObservableObject { case .technotes: return URL(string: "https://github.com/brentsimmons/NetNewsWire/tree/main/Technotes")! case .netNewsWireSlack: - return URL(string: "https://ranchero.com/netnewswire/slack")! + return URL(string: "https://netnewswire.com/slack")! case .releaseNotes: return URL.releaseNotes case .none: diff --git a/Multiplatform/macOS/Info.plist b/Multiplatform/macOS/Info.plist index c0b00660d..58377c4e4 100644 --- a/Multiplatform/macOS/Info.plist +++ b/Multiplatform/macOS/Info.plist @@ -30,7 +30,7 @@ UserAgent - NetNewsWire (RSS Reader; https://ranchero.com/netnewswire/) + NetNewsWire (RSS Reader; https://netnewswire.com/) OrganizationIdentifier $(ORGANIZATION_IDENTIFIER) DeveloperEntitlements diff --git a/Multiplatform/macOS/Preferences/Preference Panes/Advanced/AdvancedPreferencesView.swift b/Multiplatform/macOS/Preferences/Preference Panes/Advanced/AdvancedPreferencesView.swift index 44e93770b..abcecfaed 100644 --- a/Multiplatform/macOS/Preferences/Preference Panes/Advanced/AdvancedPreferencesView.swift +++ b/Multiplatform/macOS/Preferences/Preference Panes/Advanced/AdvancedPreferencesView.swift @@ -30,7 +30,7 @@ struct AdvancedPreferencesView: View { HStack { Spacer() Button("Privacy Policy", action: { - NSWorkspace.shared.open(URL(string: "https://ranchero.com/netnewswire/privacypolicy")!) + NSWorkspace.shared.open(URL(string: "https://netnewswire.com/privacypolicy")!) }) Spacer() } diff --git a/README.md b/README.md index 2dbb595f9..e60220cbb 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ It’s a free and open source feed reader for macOS and iOS. It supports [RSS](http://cyber.harvard.edu/rss/rss.html), [Atom](https://tools.ietf.org/html/rfc4287), [JSON Feed](https://jsonfeed.org/), and [RSS-in-JSON](https://github.com/scripting/Scripting-News/blob/master/rss-in-json/README.md) formats. -More info: [https://ranchero.com/netnewswire/](https://ranchero.com/netnewswire/) +More info: [https://netnewswire.com/](https://netnewswire.com/) Also see the [Technotes](Technotes/) and the [Roadmap](Technotes/Roadmap.md). @@ -14,7 +14,7 @@ Here’s [How to Support NetNewsWire](Technotes/HowToSupportNetNewsWire.markdown #### Community -[Join the Slack group](https://ranchero.com/netnewswire/slack) to talk with other NetNewsWire users — and to help out, if you’d like to, by testing, coding, writing, providing feedback, or just helping us think things through. Everybody is welcome and encouraged to join. +[Join the Slack group](https://netnewswire.com/slack) to talk with other NetNewsWire users — and to help out, if you’d like to, by testing, coding, writing, providing feedback, or just helping us think things through. Everybody is welcome and encouraged to join. Every community member is expected to abide by the code of conduct which is included in the [Contributing](CONTRIBUTING.md) page. diff --git a/Shared/ArticleStyles/ArticleStyle.swift b/Shared/ArticleStyles/ArticleStyle.swift index 01f5d86fb..97b9a3030 100644 --- a/Shared/ArticleStyles/ArticleStyle.swift +++ b/Shared/ArticleStyles/ArticleStyle.swift @@ -24,7 +24,7 @@ struct ArticleStyle: Equatable { self.path = nil; self.emptyCSS = nil - self.info = ["CreatorHomePage": "https://ranchero.com/", "CreatorName": "Ranchero Software, LLC", "Version": "1.0"] + self.info = ["CreatorHomePage": "https://netnewswire.com/", "CreatorName": "Ranchero Software", "Version": "1.0"] let sharedCSSPath = Bundle.main.path(forResource: "shared", ofType: "css")! let platformCSSPath = Bundle.main.path(forResource: "styleSheet", ofType: "css")! diff --git a/iOS/Resources/About.rtf b/iOS/Resources/About.rtf index 41b356e05..8bf10c2d4 100644 --- a/iOS/Resources/About.rtf +++ b/iOS/Resources/About.rtf @@ -1,4 +1,4 @@ -{\rtf1\ansi\ansicpg1252\cocoartf2511 +{\rtf1\ansi\ansicpg1252\cocoartf2513 \cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset0 LucidaGrande-Bold;} {\colortbl;\red255\green255\blue255;\red0\green0\blue0;\red10\green96\blue255;} {\*\expandedcolortbl;;\cssrgb\c0\c0\c0;\cssrgb\c0\c47843\c100000\cname systemBlueColor;} @@ -8,5 +8,5 @@ \f0\b\fs28 \cf2 By Brent Simmons and the Ranchero Software team \fs22 \ \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0 -{\field{\*\fldinst{HYPERLINK "https://ranchero.com/netnewswire/"}}{\fldrslt -\fs28 \cf3 ranchero.com/netnewswire/}}} \ No newline at end of file +{\field{\*\fldinst{HYPERLINK "https://netnewswire.com/"}}{\fldrslt +\fs28 \cf3 netnewswire.com}}} \ No newline at end of file diff --git a/iOS/Resources/Info.plist b/iOS/Resources/Info.plist index e843a3e9e..24e877697 100644 --- a/iOS/Resources/Info.plist +++ b/iOS/Resources/Info.plist @@ -176,6 +176,6 @@ UserAgent - NetNewsWire (RSS Reader; https://ranchero.com/netnewswire/) + NetNewsWire (RSS Reader; https://netnewswire.com/) diff --git a/iOS/Settings/SettingsViewController.swift b/iOS/Settings/SettingsViewController.swift index ae4497bb0..62ad0dda3 100644 --- a/iOS/Settings/SettingsViewController.swift +++ b/iOS/Settings/SettingsViewController.swift @@ -226,10 +226,10 @@ class SettingsViewController: UITableViewController { case 7: switch indexPath.row { case 0: - openURL("https://ranchero.com/netnewswire/help/ios/5.0/en/") + openURL("https://netnewswire.com/help/ios/5.0/en/") tableView.selectRow(at: nil, animated: true, scrollPosition: .none) case 1: - openURL("https://ranchero.com/netnewswire/") + openURL("https://netnewswire.com/") tableView.selectRow(at: nil, animated: true, scrollPosition: .none) case 2: openURL(URL.releaseNotes.absoluteString) @@ -247,7 +247,7 @@ class SettingsViewController: UITableViewController { openURL("https://github.com/brentsimmons/NetNewsWire/tree/main/Technotes") tableView.selectRow(at: nil, animated: true, scrollPosition: .none) case 7: - openURL("https://ranchero.com/netnewswire/slack") + openURL("https://netnewswire.com/slack") tableView.selectRow(at: nil, animated: true, scrollPosition: .none) case 8: let timeline = UIStoryboard.settings.instantiateController(ofType: AboutViewController.self) From 69bba93e094377503e937755666824c2d4ba532d Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sun, 21 Feb 2021 18:02:01 -0800 Subject: [PATCH 05/67] Bump version to 6.0a3. --- xcconfig/common/NetNewsWire_mac_target_common.xcconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xcconfig/common/NetNewsWire_mac_target_common.xcconfig b/xcconfig/common/NetNewsWire_mac_target_common.xcconfig index 2cc29265b..3411d11f1 100644 --- a/xcconfig/common/NetNewsWire_mac_target_common.xcconfig +++ b/xcconfig/common/NetNewsWire_mac_target_common.xcconfig @@ -1,6 +1,6 @@ // High Level Settings common to both the Mac application and any extensions we bundle with it -MARKETING_VERSION = 6.0a2 -CURRENT_PROJECT_VERSION = 6007 +MARKETING_VERSION = 6.0a3 +CURRENT_PROJECT_VERSION = 6008 ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; From 0f295affda987164d1cc1caa14f20722f721180a Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sun, 21 Feb 2021 18:07:38 -0800 Subject: [PATCH 06/67] Write 6.0a3 change notes. --- Technotes/ReleaseNotes-Mac.markdown | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Technotes/ReleaseNotes-Mac.markdown b/Technotes/ReleaseNotes-Mac.markdown index a8492d7c1..0cf662b89 100644 --- a/Technotes/ReleaseNotes-Mac.markdown +++ b/Technotes/ReleaseNotes-Mac.markdown @@ -1,5 +1,12 @@ # Mac Release Notes +### 6.0a3 build 6008 - 21 Feb 2021 + +Use the new URL for the crash report catcher (so that we actually get crash logs again) +Update other URLs to point to netnewswire.com when correct +Fix a bug with keyboard shortcuts on Big Sur +Show folders more quickly in the iCloud account when dragging a folder into that account + ### 6.0a2 build 6007 - 6 Feb 2021 Fix regression in Preferences toolbar (placement of icons was wrong on Big Sur) From 25ee9705626c5b4bda0c28df5666f564b7011440 Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Mon, 15 Feb 2021 17:49:28 -0600 Subject: [PATCH 07/67] Remove async call since the Big Sur bug that it was working around appears to be fixed. Fixes #2791 --- Mac/MainWindow/MainWindowController.swift | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/Mac/MainWindow/MainWindowController.swift b/Mac/MainWindow/MainWindowController.swift index 0c911b99f..bdacce4db 100644 --- a/Mac/MainWindow/MainWindowController.swift +++ b/Mac/MainWindow/MainWindowController.swift @@ -62,14 +62,12 @@ class MainWindowController : NSWindowController, NSUserInterfaceValidations { sharingServicePickerDelegate = SharingServicePickerDelegate(self.window) if #available(macOS 11.0, *) { - DispatchQueue.main.async { - let toolbar = NSToolbar(identifier: "MainWindowToolbar") - toolbar.allowsUserCustomization = true - toolbar.autosavesConfiguration = true - toolbar.displayMode = .iconOnly - toolbar.delegate = self - self.window?.toolbar = toolbar - } + let toolbar = NSToolbar(identifier: "MainWindowToolbar") + toolbar.allowsUserCustomization = true + toolbar.autosavesConfiguration = true + toolbar.displayMode = .iconOnly + toolbar.delegate = self + self.window?.toolbar = toolbar } else { if !AppDefaults.shared.showTitleOnMainWindow { window?.titleVisibility = .hidden From 931b1f9afdcc44a8ea84a238d4043d6d05bb91be Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Tue, 16 Feb 2021 14:24:21 -0600 Subject: [PATCH 08/67] Show Folder as it is created to give better visual feedback that a folder copy was successful. Fixes #2815 --- Mac/MainWindow/Sidebar/SidebarOutlineDataSource.swift | 2 -- 1 file changed, 2 deletions(-) diff --git a/Mac/MainWindow/Sidebar/SidebarOutlineDataSource.swift b/Mac/MainWindow/Sidebar/SidebarOutlineDataSource.swift index 11ad9399f..f403d8b25 100644 --- a/Mac/MainWindow/Sidebar/SidebarOutlineDataSource.swift +++ b/Mac/MainWindow/Sidebar/SidebarOutlineDataSource.swift @@ -490,10 +490,8 @@ private extension SidebarOutlineDataSource { return } - BatchUpdate.shared.start() replicateFolder(sourceFolder, destinationAccount: destinationAccount) { sourceAccount.removeFolder(sourceFolder) { result in - BatchUpdate.shared.end() switch result { case .success: break From afd9a47abd34f5c7712799585024e524d9acb4a1 Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Mon, 22 Feb 2021 17:50:30 -0600 Subject: [PATCH 09/67] Change so that we only show one error dialog when folder moves/copies can't find one or more feeds. --- .../Sidebar/SidebarOutlineDataSource.swift | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/Mac/MainWindow/Sidebar/SidebarOutlineDataSource.swift b/Mac/MainWindow/Sidebar/SidebarOutlineDataSource.swift index f403d8b25..384b7ba49 100644 --- a/Mac/MainWindow/Sidebar/SidebarOutlineDataSource.swift +++ b/Mac/MainWindow/Sidebar/SidebarOutlineDataSource.swift @@ -12,6 +12,18 @@ import Articles import RSCore import Account +public enum SidebarOutlineDataSourceError: LocalizedError { + case createErrorNotFound([String]) + + public var errorDescription: String? { + switch self { + case .createErrorNotFound(let feedNames): + let message = NSLocalizedString("The following feeds could not be added because they could not be found:\n", comment: "Not found") + return "\(message)\(feedNames.joined(separator: ", "))" + } + } +} + @objc final class SidebarOutlineDataSource: NSObject, NSOutlineViewDataSource { let treeController: TreeController @@ -507,6 +519,7 @@ private extension SidebarOutlineDataSource { switch result { case .success(let destinationFolder): let group = DispatchGroup() + var notFoundFeedNames = [String]() for feed in folder.topLevelWebFeeds { if let existingFeed = destinationAccount.existingWebFeed(withURL: feed.url) { group.enter() @@ -527,13 +540,20 @@ private extension SidebarOutlineDataSource { case .success: break case .failure(let error): - NSApplication.shared.presentError(error) + if let accountError = error as? AccountError, case .createErrorNotFound = accountError { + notFoundFeedNames.append(feed.nameForDisplay) + } else { + NSApplication.shared.presentError(error) + } } } } } group.notify(queue: DispatchQueue.main) { completion() + if !notFoundFeedNames.isEmpty { + NSApplication.shared.presentError(SidebarOutlineDataSourceError.createErrorNotFound(notFoundFeedNames)) + } } case .failure(let error): NSApplication.shared.presentError(error) From 1f159a5bff2dce789a88378bf3765eca45d4b261 Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Mon, 22 Feb 2021 18:50:29 -0600 Subject: [PATCH 10/67] Change drag-n-drop behavior to default to copy when dragging between accounts --- .../Sidebar/SidebarOutlineDataSource.swift | 35 ++++++++++++------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/Mac/MainWindow/Sidebar/SidebarOutlineDataSource.swift b/Mac/MainWindow/Sidebar/SidebarOutlineDataSource.swift index 384b7ba49..052f9bfca 100644 --- a/Mac/MainWindow/Sidebar/SidebarOutlineDataSource.swift +++ b/Mac/MainWindow/Sidebar/SidebarOutlineDataSource.swift @@ -215,13 +215,13 @@ private extension SidebarOutlineDataSource { return SidebarOutlineDataSource.dragOperationNone } if parentNode == dropTargetNode && index == NSOutlineViewDropOnItemIndex { - return localDragOperation() + return localDragOperation(parentNode: parentNode) } let updatedIndex = indexWhereDraggedFeedWouldAppear(dropTargetNode, draggedFeed) if parentNode !== dropTargetNode || index != updatedIndex { outlineView.setDropItem(dropTargetNode, dropChildIndex: updatedIndex) } - return localDragOperation() + return localDragOperation(parentNode: parentNode) } func validateLocalFeedsDrop(_ outlineView: NSOutlineView, _ draggedFeeds: Set, _ parentNode: Node, _ index: Int) -> NSDragOperation { @@ -238,14 +238,23 @@ private extension SidebarOutlineDataSource { if parentNode !== dropTargetNode || index != NSOutlineViewDropOnItemIndex { outlineView.setDropItem(dropTargetNode, dropChildIndex: NSOutlineViewDropOnItemIndex) } - return localDragOperation() + return localDragOperation(parentNode: parentNode) } - func localDragOperation() -> NSDragOperation { - if NSApplication.shared.currentEvent?.modifierFlags.contains(.option) ?? false { - return .copy + func localDragOperation(parentNode: Node) -> NSDragOperation { + guard let firstDraggedNode = draggedNodes?.first else { return .move } + if sameAccount(firstDraggedNode, parentNode) { + if NSApplication.shared.currentEvent?.modifierFlags.contains(.option) ?? false { + return .copy + } else { + return .move + } } else { - return .move + if NSApplication.shared.currentEvent?.modifierFlags.contains(.option) ?? false { + return .move + } else { + return .copy + } } } @@ -294,7 +303,7 @@ private extension SidebarOutlineDataSource { if index != updatedIndex { outlineView.setDropItem(parentNode, dropChildIndex: updatedIndex) } - return localDragOperation() + return localDragOperation(parentNode: parentNode) } func validateLocalFoldersDrop(_ outlineView: NSOutlineView, _ draggedFolders: Set, _ parentNode: Node, _ index: Int) -> NSDragOperation { @@ -312,7 +321,7 @@ private extension SidebarOutlineDataSource { if index != NSOutlineViewDropOnItemIndex { outlineView.setDropItem(parentNode, dropChildIndex: NSOutlineViewDropOnItemIndex) } - return localDragOperation() + return localDragOperation(parentNode: parentNode) } func copyWebFeedInAccount(node: Node, to parentNode: Node) { @@ -445,9 +454,9 @@ private extension SidebarOutlineDataSource { } } else { if NSApplication.shared.currentEvent?.modifierFlags.contains(.option) ?? false { - copyWebFeedBetweenAccounts(node: node, to: parentNode) - } else { moveWebFeedBetweenAccounts(node: node, to: parentNode) + } else { + copyWebFeedBetweenAccounts(node: node, to: parentNode) } } } @@ -571,9 +580,9 @@ private extension SidebarOutlineDataSource { draggedNodes.forEach { node in if !sameAccount(node, parentNode) { if NSApplication.shared.currentEvent?.modifierFlags.contains(.option) ?? false { - copyFolderBetweenAccounts(node: node, to: parentNode) - } else { moveFolderBetweenAccounts(node: node, to: parentNode) + } else { + copyFolderBetweenAccounts(node: node, to: parentNode) } } } From 002dabbc24426920449cd187fb7c6e3bd66ce3bc Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Mon, 22 Feb 2021 18:17:59 -0800 Subject: [PATCH 11/67] Write 6.0a4 change notes. --- Technotes/ReleaseNotes-Mac.markdown | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Technotes/ReleaseNotes-Mac.markdown b/Technotes/ReleaseNotes-Mac.markdown index 0cf662b89..124dc0b47 100644 --- a/Technotes/ReleaseNotes-Mac.markdown +++ b/Technotes/ReleaseNotes-Mac.markdown @@ -1,5 +1,11 @@ # Mac Release Notes +### 6.0a4 build 6009 - 22 Feb 2021 + +Fix a bug with keyboard shortcuts on Big Sur (for real this time) +Change drag-and-drop behavior to default to copy when dragging between accounts +Show a single error message when dragging feeds into an account and some of the feeds can’t be found + ### 6.0a3 build 6008 - 21 Feb 2021 Use the new URL for the crash report catcher (so that we actually get crash logs again) From b4babd128296be2912d3c406871f45ace2888bf1 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Mon, 22 Feb 2021 18:18:09 -0800 Subject: [PATCH 12/67] Bump version to 6.0a4. --- xcconfig/common/NetNewsWire_mac_target_common.xcconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xcconfig/common/NetNewsWire_mac_target_common.xcconfig b/xcconfig/common/NetNewsWire_mac_target_common.xcconfig index 3411d11f1..cc646fd6f 100644 --- a/xcconfig/common/NetNewsWire_mac_target_common.xcconfig +++ b/xcconfig/common/NetNewsWire_mac_target_common.xcconfig @@ -1,6 +1,6 @@ // High Level Settings common to both the Mac application and any extensions we bundle with it -MARKETING_VERSION = 6.0a3 -CURRENT_PROJECT_VERSION = 6008 +MARKETING_VERSION = 6.0a4 +CURRENT_PROJECT_VERSION = 6009 ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; From 145161ed8aff67976b19a483983de0a46d87108c Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Tue, 23 Feb 2021 17:59:19 -0600 Subject: [PATCH 13/67] Modify CloudKit add logic so that we don't wait to sync the statuses before completing the process. Fixes #2827 --- .../CloudKit/CloudKitAccountDelegate.swift | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift b/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift index 160c5e8c9..15aeebfeb 100644 --- a/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift +++ b/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift @@ -636,7 +636,9 @@ private extension CloudKitAccountDelegate { account.update(urlString, with: parsedItems) { result in switch result { case .success: - self.sendNewArticlesToTheCloud(account, feed, completion: completion) + self.sendNewArticlesToTheCloud(account, feed) + self.refreshProgress.clear() + completion(.success(feed)) case .failure(let error): self.refreshProgress.completeTasks(2) completion(.failure(error)) @@ -708,7 +710,9 @@ private extension CloudKitAccountDelegate { switch result { case .success(let externalID): feed.externalID = externalID - self.sendNewArticlesToTheCloud(account, feed, completion: completion) + self.sendNewArticlesToTheCloud(account, feed) + self.refreshProgress.clear() + completion(.success(feed)) case .failure(let error): container.removeWebFeed(feed) self.refreshProgress.completeTasks(2) @@ -740,7 +744,7 @@ private extension CloudKitAccountDelegate { } } - func sendNewArticlesToTheCloud(_ account: Account, _ feed: WebFeed, completion: @escaping (Result) -> Void) { + func sendNewArticlesToTheCloud(_ account: Account, _ feed: WebFeed) { account.fetchArticlesAsync(.webFeed(feed)) { result in switch result { case .success(let articles): @@ -749,19 +753,14 @@ private extension CloudKitAccountDelegate { self.sendArticleStatus(for: account, showProgress: true) { result in switch result { case .success: - self.articlesZone.fetchChangesInZone() { _ in - self.refreshProgress.completeTask() - completion(.success(feed)) - } + self.articlesZone.fetchChangesInZone() { _ in } case .failure(let error): - self.refreshProgress.clear() - completion(.failure(error)) + os_log(.error, log: self.log, "CloudKit Feed send articles error: %@.", error.localizedDescription) } } } case .failure(let error): - self.refreshProgress.clear() - completion(.failure(error)) + os_log(.error, log: self.log, "CloudKit Feed send articles error: %@.", error.localizedDescription) } } } From a51bcc2f0e3a783ed6be540c43d1fa6d75cdcedf Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Wed, 24 Feb 2021 15:14:38 -0600 Subject: [PATCH 14/67] Compress html and text content --- .../CloudKit/CloudKitArticlesZone.swift | 73 +++++++++++++++---- .../CloudKitArticlesZoneDelegate.swift | 21 +++++- 2 files changed, 78 insertions(+), 16 deletions(-) diff --git a/Account/Sources/Account/CloudKit/CloudKitArticlesZone.swift b/Account/Sources/Account/CloudKit/CloudKitArticlesZone.swift index 095ddcdea..6947e9c6d 100644 --- a/Account/Sources/Account/CloudKit/CloudKitArticlesZone.swift +++ b/Account/Sources/Account/CloudKit/CloudKitArticlesZone.swift @@ -25,6 +25,8 @@ final class CloudKitArticlesZone: CloudKitZone { weak var database: CKDatabase? var delegate: CloudKitZoneDelegate? = nil + var compressionQueue = DispatchQueue(label: "Articles Zone Compression Queue") + struct CloudKitArticle { static let recordType = "Article" struct Fields { @@ -33,7 +35,9 @@ final class CloudKitArticlesZone: CloudKitZone { static let uniqueID = "uniqueID" static let title = "title" static let contentHTML = "contentHTML" + static let contentHTMLData = "contentHTMLData" static let contentText = "contentText" + static let contentTextData = "contentTextData" static let url = "url" static let externalURL = "externalURL" static let summary = "summary" @@ -96,7 +100,11 @@ final class CloudKitArticlesZone: CloudKitZone { records.append(makeArticleRecord(saveArticle)) } - save(records, completion: completion) + compressionQueue.async { + self.compressArticleRecords(records) { compressedRecords in + self.save(compressedRecords, completion: completion) + } + } } func deleteArticles(_ webFeedExternalID: String, completion: @escaping ((Result) -> Void)) { @@ -130,22 +138,29 @@ final class CloudKitArticlesZone: CloudKitZone { deleteRecordIDs.append(CKRecord.ID(recordName: self.articleID(statusUpdate.articleID), zoneID: zoneID)) } } - - self.modify(recordsToSave: modifyRecords, recordIDsToDelete: deleteRecordIDs) { result in - switch result { - case .success: - self.saveIfNew(newRecords) { result in - switch result { - case .success: - completion(.success(())) - case .failure(let error): - completion(.failure(error)) + + compressionQueue.async { + self.compressArticleRecords(modifyRecords) { compressedModifyRecords in + self.compressArticleRecords(newRecords) { compressedNewRecords in + self.modify(recordsToSave: compressedModifyRecords, recordIDsToDelete: deleteRecordIDs) { result in + switch result { + case .success: + self.saveIfNew(compressedNewRecords) { result in + switch result { + case .success: + completion(.success(())) + case .failure(let error): + completion(.failure(error)) + } + } + case .failure(let error): + self.handleModifyArticlesError(error, statusUpdates: statusUpdates, completion: completion) + } } } - case .failure(let error): - self.handleModifyArticlesError(error, statusUpdates: statusUpdates, completion: completion) } } + } } @@ -237,5 +252,37 @@ private extension CloudKitArticlesZone { return record } + func compressArticleRecords(_ records: [CKRecord], completion: ([CKRecord]) -> Void ) { + var result = [CKRecord]() + + for record in records { + + if record.recordType == CloudKitArticle.recordType { + + if let contentHTML = record[CloudKitArticle.Fields.contentHTML] as? String { + let data = Data(contentHTML.utf8) as NSData + if let compressedData = try? data.compressed(using: .lzfse) { + record[CloudKitArticle.Fields.contentHTMLData] = compressedData + record[CloudKitArticle.Fields.contentHTML] = nil + } + } + + if let contentText = record[CloudKitArticle.Fields.contentText] as? String { + let data = Data(contentText.utf8) as NSData + if let compressedData = try? data.compressed(using: .lzfse) { + record[CloudKitArticle.Fields.contentTextData] = compressedData + record[CloudKitArticle.Fields.contentText] = nil + } + } + + } else { + + result.append(record) + + } + } + + completion(result) + } } diff --git a/Account/Sources/Account/CloudKit/CloudKitArticlesZoneDelegate.swift b/Account/Sources/Account/CloudKit/CloudKitArticlesZoneDelegate.swift index c3801c1ec..2f20b4204 100644 --- a/Account/Sources/Account/CloudKit/CloudKitArticlesZoneDelegate.swift +++ b/Account/Sources/Account/CloudKit/CloudKitArticlesZoneDelegate.swift @@ -23,6 +23,7 @@ class CloudKitArticlesZoneDelegate: CloudKitZoneDelegate { weak var account: Account? var database: SyncDatabase weak var articlesZone: CloudKitArticlesZone? + var compressionQueue = DispatchQueue(label: "Articles Zone Delegate Compression Queue") init(account: Account, database: SyncDatabase, articlesZone: CloudKitArticlesZone) { self.account = account @@ -134,7 +135,7 @@ private extension CloudKitArticlesZoneDelegate { } group.enter() - DispatchQueue.global(qos: .utility).async { + compressionQueue.async { let parsedItems = records.compactMap { self.makeParsedItem($0) } let webFeedIDsAndItems = Dictionary(grouping: parsedItems, by: { item in item.feedURL } ).mapValues { Set($0) } @@ -199,6 +200,20 @@ private extension CloudKitArticlesZoneDelegate { return nil } + var contentHTML = articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.contentHTML] as? String + if let contentHTMLData = articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.contentHTMLData] as? NSData { + if let decompressedContentHTMLData = try? contentHTMLData.decompressed(using: .lzfse) { + contentHTML = String(data: decompressedContentHTMLData as Data, encoding: .utf8) + } + } + + var contentText = articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.contentText] as? String + if let contentTextData = articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.contentTextData] as? NSData { + if let decompressedContentTextData = try? contentTextData.decompressed(using: .lzfse) { + contentText = String(data: decompressedContentTextData as Data, encoding: .utf8) + } + } + let parsedItem = ParsedItem(syncServiceID: nil, uniqueID: uniqueID, feedURL: webFeedURL, @@ -206,8 +221,8 @@ private extension CloudKitArticlesZoneDelegate { externalURL: articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.externalURL] as? String, title: articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.title] as? String, language: nil, - contentHTML: articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.contentHTML] as? String, - contentText: articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.contentText] as? String, + contentHTML: contentHTML, + contentText: contentText, summary: articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.summary] as? String, imageURL: articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.imageURL] as? String, bannerImageURL: articleRecord[CloudKitArticlesZone.CloudKitArticle.Fields.imageURL] as? String, From 8a9a9910cc130e93a670bf1beb0d25cace3935e7 Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Wed, 24 Feb 2021 15:33:24 -0600 Subject: [PATCH 15/67] Simplify the compression logic --- .../CloudKit/CloudKitArticlesZone.swift | 41 ++++++++----------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/Account/Sources/Account/CloudKit/CloudKitArticlesZone.swift b/Account/Sources/Account/CloudKit/CloudKitArticlesZone.swift index 6947e9c6d..5c8733317 100644 --- a/Account/Sources/Account/CloudKit/CloudKitArticlesZone.swift +++ b/Account/Sources/Account/CloudKit/CloudKitArticlesZone.swift @@ -101,9 +101,8 @@ final class CloudKitArticlesZone: CloudKitZone { } compressionQueue.async { - self.compressArticleRecords(records) { compressedRecords in - self.save(compressedRecords, completion: completion) - } + let compressedRecords = self.compressArticleRecords(records) + self.save(compressedRecords, completion: completion) } } @@ -140,23 +139,21 @@ final class CloudKitArticlesZone: CloudKitZone { } compressionQueue.async { - self.compressArticleRecords(modifyRecords) { compressedModifyRecords in - self.compressArticleRecords(newRecords) { compressedNewRecords in - self.modify(recordsToSave: compressedModifyRecords, recordIDsToDelete: deleteRecordIDs) { result in + let compressedModifyRecords = self.compressArticleRecords(modifyRecords) + self.modify(recordsToSave: compressedModifyRecords, recordIDsToDelete: deleteRecordIDs) { result in + switch result { + case .success: + let compressedNewRecords = self.compressArticleRecords(newRecords) + self.saveIfNew(compressedNewRecords) { result in switch result { case .success: - self.saveIfNew(compressedNewRecords) { result in - switch result { - case .success: - completion(.success(())) - case .failure(let error): - completion(.failure(error)) - } - } + completion(.success(())) case .failure(let error): - self.handleModifyArticlesError(error, statusUpdates: statusUpdates, completion: completion) + completion(.failure(error)) } } + case .failure(let error): + self.handleModifyArticlesError(error, statusUpdates: statusUpdates, completion: completion) } } } @@ -252,7 +249,7 @@ private extension CloudKitArticlesZone { return record } - func compressArticleRecords(_ records: [CKRecord], completion: ([CKRecord]) -> Void ) { + func compressArticleRecords(_ records: [CKRecord]) -> [CKRecord] { var result = [CKRecord]() for record in records { @@ -262,7 +259,7 @@ private extension CloudKitArticlesZone { if let contentHTML = record[CloudKitArticle.Fields.contentHTML] as? String { let data = Data(contentHTML.utf8) as NSData if let compressedData = try? data.compressed(using: .lzfse) { - record[CloudKitArticle.Fields.contentHTMLData] = compressedData + record[CloudKitArticle.Fields.contentHTMLData] = compressedData as Data record[CloudKitArticle.Fields.contentHTML] = nil } } @@ -270,19 +267,17 @@ private extension CloudKitArticlesZone { if let contentText = record[CloudKitArticle.Fields.contentText] as? String { let data = Data(contentText.utf8) as NSData if let compressedData = try? data.compressed(using: .lzfse) { - record[CloudKitArticle.Fields.contentTextData] = compressedData + record[CloudKitArticle.Fields.contentTextData] = compressedData as Data record[CloudKitArticle.Fields.contentText] = nil } } - } else { - - result.append(record) - } + + result.append(record) } - completion(result) + return result } } From 74298e7cde32c5e1f9ab3a48d832b0976c574406 Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Fri, 26 Feb 2021 17:38:26 -0600 Subject: [PATCH 16/67] Add hidden GruberFeedDoubleClickMarkAsRead preference --- Mac/AppDefaults.swift | 10 ++++++++++ Mac/MainWindow/Sidebar/SidebarViewController.swift | 5 +++++ 2 files changed, 15 insertions(+) diff --git a/Mac/AppDefaults.swift b/Mac/AppDefaults.swift index 8aff09137..f40011bbb 100644 --- a/Mac/AppDefaults.swift +++ b/Mac/AppDefaults.swift @@ -44,6 +44,7 @@ final class AppDefaults { static let timelineShowsSeparators = "CorreiaSeparators" static let showTitleOnMainWindow = "KafasisTitleMode" static let hideDockUnreadCount = "JustinMillerHideDockUnreadCount" + static let feedDoubleClickMarkAsRead = "GruberFeedDoubleClickMarkAsRead" #if !MAC_APP_STORE static let webInspectorEnabled = "WebInspectorEnabled" @@ -203,6 +204,15 @@ final class AppDefaults { } } + var feedDoubleClickMarkAsRead: Bool { + get { + return AppDefaults.bool(for: Key.feedDoubleClickMarkAsRead) + } + set { + AppDefaults.setBool(for: Key.feedDoubleClickMarkAsRead, newValue) + } + } + #if !MAC_APP_STORE var webInspectorEnabled: Bool { get { diff --git a/Mac/MainWindow/Sidebar/SidebarViewController.swift b/Mac/MainWindow/Sidebar/SidebarViewController.swift index 277be185e..d902874c7 100644 --- a/Mac/MainWindow/Sidebar/SidebarViewController.swift +++ b/Mac/MainWindow/Sidebar/SidebarViewController.swift @@ -255,6 +255,11 @@ protocol SidebarDelegate: class { guard outlineView.clickedRow == outlineView.selectedRow else { return } + if AppDefaults.shared.feedDoubleClickMarkAsRead, let articles = try? singleSelectedWebFeed?.fetchUnreadArticles() { + if let undoManager = undoManager, let markReadCommand = MarkStatusCommand(initialArticles: Array(articles), markingRead: true, undoManager: undoManager) { + runCommand(markReadCommand) + } + } openInBrowser(sender) } From 035759947a4f0647be35796a6c37326cd0aa74d7 Mon Sep 17 00:00:00 2001 From: Collin Donnell Date: Sat, 27 Feb 2021 16:32:57 -0800 Subject: [PATCH 17/67] Fix #2833: Titlebar is overlapped by toolbar in fullscreen Fix issue where detail web view would be overlapped by the toolbar in full screen by setting web view constraints to use the `safeAreaLayoutGuide` in macOS 11+. --- .../Detail/DetailWebViewController.swift | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/Mac/MainWindow/Detail/DetailWebViewController.swift b/Mac/MainWindow/Detail/DetailWebViewController.swift index b1f8de853..843fabd44 100644 --- a/Mac/MainWindow/Detail/DetailWebViewController.swift +++ b/Mac/MainWindow/Detail/DetailWebViewController.swift @@ -98,14 +98,25 @@ final class DetailWebViewController: NSViewController, WKUIDelegate { box.addSubview(webView) - let constraints = [ - webView.topAnchor.constraint(equalTo: view.topAnchor), - webView.bottomAnchor.constraint(equalTo: view.bottomAnchor), - webView.leadingAnchor.constraint(equalTo: view.leadingAnchor), - webView.trailingAnchor.constraint(equalTo: view.trailingAnchor), - ] + // Use the safe area layout guides if they are available. + if #available(OSX 11.0, *) { + let constraints = [ + webView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), + webView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor), + webView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor), + webView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor), + ] + NSLayoutConstraint.activate(constraints) + } else { + let constraints = [ + webView.topAnchor.constraint(equalTo: view.topAnchor), + webView.bottomAnchor.constraint(equalTo: view.bottomAnchor), + webView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + webView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + ] + NSLayoutConstraint.activate(constraints) + } - NSLayoutConstraint.activate(constraints) // Hide the web view until the first reload (navigation) is complete (plus some delay) to avoid the awful white flash that happens on the initial display in dark mode. // See bug #901. From bb5a0abb9a2d7721fe8ed0da7f46f202dc1c02fa Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Tue, 2 Mar 2021 22:08:11 -0800 Subject: [PATCH 18/67] Update crash log URL to the new crash log catcher on our new services.netnewswire.com server. --- Mac/CrashReporter/CrashReporter.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mac/CrashReporter/CrashReporter.swift b/Mac/CrashReporter/CrashReporter.swift index 9c15e602e..b37810a9d 100644 --- a/Mac/CrashReporter/CrashReporter.swift +++ b/Mac/CrashReporter/CrashReporter.swift @@ -42,7 +42,7 @@ struct CrashReporter { } static func sendCrashLogText(_ crashLogText: String) { - var request = URLRequest(url: URL(string: "https://netnewswire.com/crashreportcatcher.php")!) + var request = URLRequest(url: URL(string: "https://services.netnewswire.com/reportCrash.php")!) request.httpMethod = HTTPMethod.post let boundary = "0xKhTmLbOuNdArY" From b6f62c5f98b66317723c480de3a20f8b93a5a9ee Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Wed, 3 Mar 2021 17:30:59 -0800 Subject: [PATCH 19/67] Bump version to 6.0a5. --- xcconfig/common/NetNewsWire_mac_target_common.xcconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xcconfig/common/NetNewsWire_mac_target_common.xcconfig b/xcconfig/common/NetNewsWire_mac_target_common.xcconfig index cc646fd6f..1217f2818 100644 --- a/xcconfig/common/NetNewsWire_mac_target_common.xcconfig +++ b/xcconfig/common/NetNewsWire_mac_target_common.xcconfig @@ -1,6 +1,6 @@ // High Level Settings common to both the Mac application and any extensions we bundle with it -MARKETING_VERSION = 6.0a4 -CURRENT_PROJECT_VERSION = 6009 +MARKETING_VERSION = 6.0a5 +CURRENT_PROJECT_VERSION = 6010 ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; From 09cdfc6522a20e939d8e5cae45160d8e018f20b4 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Wed, 3 Mar 2021 17:35:57 -0800 Subject: [PATCH 20/67] Write release notes for 6.0a5. --- Technotes/ReleaseNotes-Mac.markdown | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Technotes/ReleaseNotes-Mac.markdown b/Technotes/ReleaseNotes-Mac.markdown index 124dc0b47..81508eb3d 100644 --- a/Technotes/ReleaseNotes-Mac.markdown +++ b/Technotes/ReleaseNotes-Mac.markdown @@ -1,5 +1,13 @@ # Mac Release Notes +### 6.0a5 build 6010 - 3 Mar 2021 + +Performance boost: use compression with content synced in CloudKit +Fixed bug where detail view title bar could be overlapped by toolbar when in full screen +Fixed bug where add-feed window could block when syncing CloudKit statuses +Added hidden pref to mark all as read in a feed when double-clicking on it in the sidebar and opening its home page (defaults write com.ranchero.NetNewsWire-Evergreen GruberFeedDoubleClickMarkAsRead -bool true) +Switched the crash log catcher URL to our brand-new crash log catcher server + ### 6.0a4 build 6009 - 22 Feb 2021 Fix a bug with keyboard shortcuts on Big Sur (for real this time) From 2ca06eeae76f43ccc07a3d88d324cdf9273414ca Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Fri, 5 Mar 2021 12:45:15 -0600 Subject: [PATCH 21/67] Remove containing box for web view. Fixes #2848 --- .../Detail/DetailWebViewController.swift | 12 +----- .../Contents.json | 38 ------------------- 2 files changed, 1 insertion(+), 49 deletions(-) delete mode 100644 Mac/Resources/Assets.xcassets/webviewBackgroundColor.colorset/Contents.json diff --git a/Mac/MainWindow/Detail/DetailWebViewController.swift b/Mac/MainWindow/Detail/DetailWebViewController.swift index 843fabd44..857a34b1b 100644 --- a/Mac/MainWindow/Detail/DetailWebViewController.swift +++ b/Mac/MainWindow/Detail/DetailWebViewController.swift @@ -63,16 +63,6 @@ final class DetailWebViewController: NSViewController, WKUIDelegate { } override func loadView() { - // Wrap the webview in a box configured with the same background color that the web view uses - let box = NSBox(frame: .zero) - box.boxType = .custom - box.isTransparent = true - box.titlePosition = .noTitle - box.contentViewMargins = .zero - box.fillColor = NSColor(named: "webviewBackgroundColor")! - - view = box - let preferences = WKPreferences() preferences.minimumFontSize = 12.0 preferences.javaScriptCanOpenWindowsAutomatically = false @@ -96,7 +86,7 @@ final class DetailWebViewController: NSViewController, WKUIDelegate { webView.customUserAgent = userAgent } - box.addSubview(webView) + view = webView // Use the safe area layout guides if they are available. if #available(OSX 11.0, *) { diff --git a/Mac/Resources/Assets.xcassets/webviewBackgroundColor.colorset/Contents.json b/Mac/Resources/Assets.xcassets/webviewBackgroundColor.colorset/Contents.json deleted file mode 100644 index c488d1243..000000000 --- a/Mac/Resources/Assets.xcassets/webviewBackgroundColor.colorset/Contents.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "info" : { - "version" : 1, - "author" : "xcode" - }, - "colors" : [ - { - "idiom" : "universal", - "color" : { - "color-space" : "srgb", - "components" : { - "red" : "1.000", - "alpha" : "1.000", - "blue" : "1.000", - "green" : "1.000" - } - } - }, - { - "idiom" : "universal", - "appearances" : [ - { - "appearance" : "luminosity", - "value" : "dark" - } - ], - "color" : { - "color-space" : "display-p3", - "components" : { - "red" : "0.176", - "alpha" : "1.000", - "blue" : "0.176", - "green" : "0.176" - } - } - } - ] -} \ No newline at end of file From ab2bd9db26c5931f30d840cb0c84128e7176ad04 Mon Sep 17 00:00:00 2001 From: Stuart Breckenridge Date: Sat, 6 Mar 2021 10:45:58 +0800 Subject: [PATCH 22/67] tweaks to pre/code css styles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follows Apple’s example. • `code` within normal text is sized to 1em • `code` within `pre` is sized slightly smaller and the letter-spacing is tightened --- Shared/Article Rendering/shared.css | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Shared/Article Rendering/shared.css b/Shared/Article Rendering/shared.css index fa2a5920d..9989734c4 100644 --- a/Shared/Article Rendering/shared.css +++ b/Shared/Article Rendering/shared.css @@ -137,7 +137,6 @@ pre { margin: 0; overflow: auto; overflow-y: hidden; - word-wrap: normal; word-break: normal; } @@ -145,12 +144,18 @@ pre { pre { line-height: 1.4286em; } + code, pre { font-family: "SF Mono", Menlo, "Courier New", Courier, monospace; - font-size: .8235em; + font-size: 1em; -webkit-hyphens: none; } +pre code { + letter-spacing: -.027em; + font-size: 0.9375em; +} + .nnw-overflow { overflow-x: auto; } From a7abde04abdc9c6251d96e81f51873989a97c010 Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Sat, 6 Mar 2021 16:25:10 -0600 Subject: [PATCH 23/67] Fix variable name --- Mac/MainWindow/IconView.swift | 12 ++++++------ Multiplatform/iOS/Article/IconView.swift | 12 ++++++------ Multiplatform/macOS/Article/IconView.swift | 12 ++++++------ iOS/IconView.swift | 12 ++++++------ 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/Mac/MainWindow/IconView.swift b/Mac/MainWindow/IconView.swift index 401f41cb0..edbbbace8 100644 --- a/Mac/MainWindow/IconView.swift +++ b/Mac/MainWindow/IconView.swift @@ -17,15 +17,15 @@ final class IconView: NSView { if NSApplication.shared.effectiveAppearance.isDarkMode { if self.iconImage?.isDark ?? false { - self.isDisconcernable = false + self.isDiscernable = false } else { - self.isDisconcernable = true + self.isDiscernable = true } } else { if self.iconImage?.isBright ?? false { - self.isDisconcernable = false + self.isDiscernable = false } else { - self.isDisconcernable = true + self.isDiscernable = true } } @@ -35,7 +35,7 @@ final class IconView: NSView { } } - private var isDisconcernable = true + private var isDiscernable = true override var isFlipped: Bool { return true @@ -85,7 +85,7 @@ final class IconView: NSView { override func draw(_ dirtyRect: NSRect) { guard !(iconImage?.isBackgroundSupressed ?? false) else { return } - guard hasExposedVerticalBackground || !isDisconcernable else { return } + guard hasExposedVerticalBackground || !isDiscernable else { return } let color = NSApplication.shared.effectiveAppearance.isDarkMode ? IconView.darkBackgroundColor : IconView.lightBackgroundColor color.set() diff --git a/Multiplatform/iOS/Article/IconView.swift b/Multiplatform/iOS/Article/IconView.swift index b187821cf..dc44dc0d6 100644 --- a/Multiplatform/iOS/Article/IconView.swift +++ b/Multiplatform/iOS/Article/IconView.swift @@ -17,18 +17,18 @@ final class IconView: UIView { if self.traitCollection.userInterfaceStyle == .dark { if self.iconImage?.isDark ?? false { - self.isDisconcernable = false + self.isDiscernable = false self.setNeedsLayout() } else { - self.isDisconcernable = true + self.isDiscernable = true self.setNeedsLayout() } } else { if self.iconImage?.isBright ?? false { - self.isDisconcernable = false + self.isDiscernable = false self.setNeedsLayout() } else { - self.isDisconcernable = true + self.isDiscernable = true self.setNeedsLayout() } } @@ -37,7 +37,7 @@ final class IconView: UIView { } } - private var isDisconcernable = true + private var isDiscernable = true private let imageView: UIImageView = { let imageView = UIImageView(image: AppAssets.faviconTemplateImage) @@ -79,7 +79,7 @@ final class IconView: UIView { override func layoutSubviews() { imageView.setFrameIfNotEqual(rectForImageView()) - if (iconImage != nil && isVerticalBackgroundExposed) || !isDisconcernable { + if (iconImage != nil && isVerticalBackgroundExposed) || !isDiscernable { backgroundColor = AppAssets.uiIconBackgroundColor } else { backgroundColor = nil diff --git a/Multiplatform/macOS/Article/IconView.swift b/Multiplatform/macOS/Article/IconView.swift index 7a721c4f8..6513d485d 100644 --- a/Multiplatform/macOS/Article/IconView.swift +++ b/Multiplatform/macOS/Article/IconView.swift @@ -17,15 +17,15 @@ final class IconView: NSView { if NSApplication.shared.effectiveAppearance.isDarkMode { if self.iconImage?.isDark ?? false { - self.isDisconcernable = false + self.isDiscernable = false } else { - self.isDisconcernable = true + self.isDiscernable = true } } else { if self.iconImage?.isBright ?? false { - self.isDisconcernable = false + self.isDiscernable = false } else { - self.isDisconcernable = true + self.isDiscernable = true } } @@ -35,7 +35,7 @@ final class IconView: NSView { } } - private var isDisconcernable = true + private var isDiscernable = true override var isFlipped: Bool { return true @@ -81,7 +81,7 @@ final class IconView: NSView { } override func draw(_ dirtyRect: NSRect) { - guard hasExposedVerticalBackground || !isDisconcernable else { + guard hasExposedVerticalBackground || !isDiscernable else { return } diff --git a/iOS/IconView.swift b/iOS/IconView.swift index e342c010f..55cd454cc 100644 --- a/iOS/IconView.swift +++ b/iOS/IconView.swift @@ -17,18 +17,18 @@ final class IconView: UIView { if self.traitCollection.userInterfaceStyle == .dark { if self.iconImage?.isDark ?? false { - self.isDisconcernable = false + self.isDiscernable = false self.setNeedsLayout() } else { - self.isDisconcernable = true + self.isDiscernable = true self.setNeedsLayout() } } else { if self.iconImage?.isBright ?? false { - self.isDisconcernable = false + self.isDiscernable = false self.setNeedsLayout() } else { - self.isDisconcernable = true + self.isDiscernable = true self.setNeedsLayout() } } @@ -37,7 +37,7 @@ final class IconView: UIView { } } - private var isDisconcernable = true + private var isDiscernable = true private let imageView: UIImageView = { let imageView = NonIntrinsicImageView(image: AppAssets.faviconTemplateImage) @@ -79,7 +79,7 @@ final class IconView: UIView { override func layoutSubviews() { imageView.setFrameIfNotEqual(rectForImageView()) - if !isBackgroundSuppressed && ((iconImage != nil && isVerticalBackgroundExposed) || !isDisconcernable) { + if !isBackgroundSuppressed && ((iconImage != nil && isVerticalBackgroundExposed) || !isDiscernable) { backgroundColor = AppAssets.iconBackgroundColor } else { backgroundColor = nil From 91a825343a412d6a01639b033c5878ae28edc0ac Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sat, 6 Mar 2021 14:44:58 -0800 Subject: [PATCH 24/67] Add Debug > Force Crash command. Also: let the test for crash report sending work in production. --- Mac/AppDelegate.swift | 8 +++++--- Mac/Base.lproj/Main.storyboard | 14 +++++++++++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/Mac/AppDelegate.swift b/Mac/AppDelegate.swift index 52b0abd0f..b5e34b3b4 100644 --- a/Mac/AppDelegate.swift +++ b/Mac/AppDelegate.swift @@ -715,9 +715,11 @@ extension AppDelegate { } @IBAction func debugTestCrashReportSending(_ sender: Any?) { - #if DEBUG - CrashReporter.sendCrashLogText("This is a test. Hi, Brent.") - #endif + CrashReporter.sendCrashLogText("This is a test. Hi, Brent.") + } + + @IBAction func forceCrash(_ sender: Any?) { + fatalError("This is a deliberate crash.") } @IBAction func openApplicationSupportFolder(_ sender: Any?) { diff --git a/Mac/Base.lproj/Main.storyboard b/Mac/Base.lproj/Main.storyboard index 9e3bdf707..a1f665aa2 100644 --- a/Mac/Base.lproj/Main.storyboard +++ b/Mac/Base.lproj/Main.storyboard @@ -1,8 +1,8 @@ - + - + @@ -516,6 +516,7 @@ + @@ -528,6 +529,13 @@ + + + + + + + @@ -682,7 +690,7 @@ - + From 328c249bef2601c4312bfa28d69e72df41e203f8 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sat, 6 Mar 2021 14:45:10 -0800 Subject: [PATCH 25/67] Bump to 6.0a6. --- xcconfig/common/NetNewsWire_mac_target_common.xcconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xcconfig/common/NetNewsWire_mac_target_common.xcconfig b/xcconfig/common/NetNewsWire_mac_target_common.xcconfig index 1217f2818..9259230f1 100644 --- a/xcconfig/common/NetNewsWire_mac_target_common.xcconfig +++ b/xcconfig/common/NetNewsWire_mac_target_common.xcconfig @@ -1,6 +1,6 @@ // High Level Settings common to both the Mac application and any extensions we bundle with it -MARKETING_VERSION = 6.0a5 -CURRENT_PROJECT_VERSION = 6010 +MARKETING_VERSION = 6.0a6 +CURRENT_PROJECT_VERSION = 6011 ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; From 4abd53b0bafc260dee448e897b74dcdfdead241b Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sat, 6 Mar 2021 14:52:15 -0800 Subject: [PATCH 26/67] Write change notes for 6.0a6. --- Technotes/ReleaseNotes-Mac.markdown | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Technotes/ReleaseNotes-Mac.markdown b/Technotes/ReleaseNotes-Mac.markdown index 81508eb3d..0d0a8dc46 100644 --- a/Technotes/ReleaseNotes-Mac.markdown +++ b/Technotes/ReleaseNotes-Mac.markdown @@ -1,5 +1,12 @@ # Mac Release Notes +### 6.0a6 build 6011 - 6 Mar 2021 + +Article view: make code and preformatted fonts and sizes follow Apple’s precedents more closely +Article view: removed a stray line next to the timeline/article separator +Debug menu: add Force Crash command (beware: works in production) +Debug menu: allow Test Crash Log Sender to work in production + ### 6.0a5 build 6010 - 3 Mar 2021 Performance boost: use compression with content synced in CloudKit From 8dc6e4e33281b59c53e52379b9eb4163088720ae Mon Sep 17 00:00:00 2001 From: Stuart Breckenridge Date: Sun, 7 Mar 2021 14:20:03 +0800 Subject: [PATCH 27/67] Contraint Changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit • Fixes #2850 • #2634: resizing vertically downards (expanding) is smooth --- .../Detail/DetailWebViewController.swift | 8 +------- Shared/Extensions/NSView-Extensions.swift | 20 ++++++++++++++----- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/Mac/MainWindow/Detail/DetailWebViewController.swift b/Mac/MainWindow/Detail/DetailWebViewController.swift index 857a34b1b..fbb97fa4f 100644 --- a/Mac/MainWindow/Detail/DetailWebViewController.swift +++ b/Mac/MainWindow/Detail/DetailWebViewController.swift @@ -90,13 +90,7 @@ final class DetailWebViewController: NSViewController, WKUIDelegate { // Use the safe area layout guides if they are available. if #available(OSX 11.0, *) { - let constraints = [ - webView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), - webView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor), - webView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor), - webView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor), - ] - NSLayoutConstraint.activate(constraints) + // These constraints have been removed as they were unsatisfyable after removing NSBox. } else { let constraints = [ webView.topAnchor.constraint(equalTo: view.topAnchor), diff --git a/Shared/Extensions/NSView-Extensions.swift b/Shared/Extensions/NSView-Extensions.swift index 2c5aff1d0..e9449208e 100644 --- a/Shared/Extensions/NSView-Extensions.swift +++ b/Shared/Extensions/NSView-Extensions.swift @@ -11,10 +11,20 @@ import AppKit extension NSView { func constraintsToMakeSubViewFullSize(_ subview: NSView) -> [NSLayoutConstraint] { - let leadingConstraint = NSLayoutConstraint(item: subview, attribute: .leading, relatedBy: .equal, toItem: self, attribute: .leading, multiplier: 1.0, constant: 0.0) - let trailingConstraint = NSLayoutConstraint(item: subview, attribute: .trailing, relatedBy: .equal, toItem: self, attribute: .trailing, multiplier: 1.0, constant: 0.0) - let topConstraint = NSLayoutConstraint(item: subview, attribute: .top, relatedBy: .equal, toItem: self, attribute: .top, multiplier: 1.0, constant: 0.0) - let bottomConstraint = NSLayoutConstraint(item: subview, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1.0, constant: 0.0) - return [leadingConstraint, trailingConstraint, topConstraint, bottomConstraint] + + if #available(macOS 11, *) { + let leadingConstraint = NSLayoutConstraint(item: subview, attribute: .leading, relatedBy: .equal, toItem: self.safeAreaLayoutGuide, attribute: .leading, multiplier: 1.0, constant: 0.0) + let trailingConstraint = NSLayoutConstraint(item: subview, attribute: .trailing, relatedBy: .equal, toItem: self.safeAreaLayoutGuide, attribute: .trailing, multiplier: 1.0, constant: 0.0) + let topConstraint = NSLayoutConstraint(item: subview, attribute: .top, relatedBy: .equal, toItem: self.safeAreaLayoutGuide, attribute: .top, multiplier: 1.0, constant: 0.0) + let bottomConstraint = NSLayoutConstraint(item: subview, attribute: .bottom, relatedBy: .equal, toItem: self.safeAreaLayoutGuide, attribute: .bottom, multiplier: 1.0, constant: 0.0) + return [leadingConstraint, trailingConstraint, topConstraint, bottomConstraint] + } else { + let leadingConstraint = NSLayoutConstraint(item: subview, attribute: .leading, relatedBy: .equal, toItem: self, attribute: .leading, multiplier: 1.0, constant: 0.0) + let trailingConstraint = NSLayoutConstraint(item: subview, attribute: .trailing, relatedBy: .equal, toItem: self, attribute: .trailing, multiplier: 1.0, constant: 0.0) + let topConstraint = NSLayoutConstraint(item: subview, attribute: .top, relatedBy: .equal, toItem: self, attribute: .top, multiplier: 1.0, constant: 0.0) + let bottomConstraint = NSLayoutConstraint(item: subview, attribute: .bottom, relatedBy: .equal, toItem: self, attribute: .bottom, multiplier: 1.0, constant: 0.0) + return [leadingConstraint, trailingConstraint, topConstraint, bottomConstraint] + } + } } From 7a653db1dd553ce723c27565f608887545988f15 Mon Sep 17 00:00:00 2001 From: Stuart Breckenridge Date: Sun, 7 Mar 2021 15:51:43 +0800 Subject: [PATCH 28/67] typo --- Mac/MainWindow/Detail/DetailWebViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mac/MainWindow/Detail/DetailWebViewController.swift b/Mac/MainWindow/Detail/DetailWebViewController.swift index fbb97fa4f..b661a3e86 100644 --- a/Mac/MainWindow/Detail/DetailWebViewController.swift +++ b/Mac/MainWindow/Detail/DetailWebViewController.swift @@ -90,7 +90,7 @@ final class DetailWebViewController: NSViewController, WKUIDelegate { // Use the safe area layout guides if they are available. if #available(OSX 11.0, *) { - // These constraints have been removed as they were unsatisfyable after removing NSBox. + // These constraints have been removed as they were unsatisfiable after removing NSBox. } else { let constraints = [ webView.topAnchor.constraint(equalTo: view.topAnchor), From 86981a0c5b29d50c9d1d23a337f987572283fbab Mon Sep 17 00:00:00 2001 From: Stuart Breckenridge Date: Sun, 7 Mar 2021 16:47:39 +0800 Subject: [PATCH 29/67] #2597 Fixes #2597: Toggles a small window height change to get webview to behave on macOS 11. --- Mac/MainWindow/Detail/DetailWebViewController.swift | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Mac/MainWindow/Detail/DetailWebViewController.swift b/Mac/MainWindow/Detail/DetailWebViewController.swift index b661a3e86..5ad51eae5 100644 --- a/Mac/MainWindow/Detail/DetailWebViewController.swift +++ b/Mac/MainWindow/Detail/DetailWebViewController.swift @@ -116,6 +116,7 @@ final class DetailWebViewController: NSViewController, WKUIDelegate { NotificationCenter.default.addObserver(self, selector: #selector(avatarDidBecomeAvailable(_:)), name: .AvatarDidBecomeAvailable, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(faviconDidBecomeAvailable(_:)), name: .FaviconDidBecomeAvailable, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(userDefaultsDidChange(_:)), name: UserDefaults.didChangeNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(bigSurOffsetFix(_:)), name: NSWindow.didExitFullScreenNotification, object: nil) webView.loadFileURL(ArticleRenderer.blank.url, allowingReadAccessTo: ArticleRenderer.blank.baseURL) } @@ -141,6 +142,18 @@ final class DetailWebViewController: NSViewController, WKUIDelegate { } } + /// On macOS 11, when a user exits full screen, the webview's origin.y is offset by a sizeable amount. This function adjusts the height of the window height by 1pt which puts the webview back in the correct place. This is an issue with SwiftUI and AppKit. + @objc func bigSurOffsetFix(_ note: Notification) { + if #available(macOS 11, *) { + // On macOS 11, at the end of a resize down + guard var frame = self.view.window?.frame else { + return + } + frame.size = NSSize(width: self.view.window!.frame.width, height: self.view.window!.frame.height - 1) + self.view.window!.setFrame(frame, display: true) + } + } + // MARK: Media Functions func stopMediaPlayback() { From 2e12f5a078f5c3a5223ccf039cab94df6dfb983d Mon Sep 17 00:00:00 2001 From: Stuart Breckenridge Date: Sun, 7 Mar 2021 21:34:52 +0800 Subject: [PATCH 30/67] removes code comment --- Mac/MainWindow/Detail/DetailWebViewController.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/Mac/MainWindow/Detail/DetailWebViewController.swift b/Mac/MainWindow/Detail/DetailWebViewController.swift index 5ad51eae5..5c6f9a5ed 100644 --- a/Mac/MainWindow/Detail/DetailWebViewController.swift +++ b/Mac/MainWindow/Detail/DetailWebViewController.swift @@ -145,7 +145,6 @@ final class DetailWebViewController: NSViewController, WKUIDelegate { /// On macOS 11, when a user exits full screen, the webview's origin.y is offset by a sizeable amount. This function adjusts the height of the window height by 1pt which puts the webview back in the correct place. This is an issue with SwiftUI and AppKit. @objc func bigSurOffsetFix(_ note: Notification) { if #available(macOS 11, *) { - // On macOS 11, at the end of a resize down guard var frame = self.view.window?.frame else { return } From 4ff7e4ccbc99caa879ca710beab620ae6e0d3221 Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Sun, 7 Mar 2021 13:03:28 -0600 Subject: [PATCH 31/67] Update to the latest RSCore. Fixes #2685 --- .../project.xcworkspace/xcshareddata/swiftpm/Package.resolved | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NetNewsWire.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/NetNewsWire.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 71a837402..ae2eb2544 100644 --- a/NetNewsWire.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/NetNewsWire.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -60,8 +60,8 @@ "repositoryURL": "https://github.com/Ranchero-Software/RSCore.git", "state": { "branch": null, - "revision": "6b2ef2580968905af825c40442dc0ba3126032c0", - "version": "1.0.2" + "revision": "7070f8a7f5cad5fcbe2444a4b6265af20efd85a6", + "version": "1.0.3" } }, { From 2b816fee4b0e0b29980f32c29759137b1c5e9fe6 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sun, 7 Mar 2021 12:06:13 -0800 Subject: [PATCH 32/67] Update change notes. Bump version to 6.0b1. --- Technotes/ReleaseNotes-Mac.markdown | 5 +++++ xcconfig/common/NetNewsWire_mac_target_common.xcconfig | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Technotes/ReleaseNotes-Mac.markdown b/Technotes/ReleaseNotes-Mac.markdown index 0d0a8dc46..c3aee6cb9 100644 --- a/Technotes/ReleaseNotes-Mac.markdown +++ b/Technotes/ReleaseNotes-Mac.markdown @@ -1,5 +1,10 @@ # Mac Release Notes +### 6.0b1 build 6012 - 7 Mar 2021 + +Article view: fixed several layout edge cases, including with fullscreen +Timeline: fixed a bug scrolling up via arrow key where a row might not be fully visible when it should be + ### 6.0a6 build 6011 - 6 Mar 2021 Article view: make code and preformatted fonts and sizes follow Apple’s precedents more closely diff --git a/xcconfig/common/NetNewsWire_mac_target_common.xcconfig b/xcconfig/common/NetNewsWire_mac_target_common.xcconfig index 9259230f1..aa6e7d1d0 100644 --- a/xcconfig/common/NetNewsWire_mac_target_common.xcconfig +++ b/xcconfig/common/NetNewsWire_mac_target_common.xcconfig @@ -1,6 +1,6 @@ // High Level Settings common to both the Mac application and any extensions we bundle with it -MARKETING_VERSION = 6.0a6 -CURRENT_PROJECT_VERSION = 6011 +MARKETING_VERSION = 6.0b1 +CURRENT_PROJECT_VERSION = 6012 ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; From 27b9326d07024f2e34d745985a5970b22c905f52 Mon Sep 17 00:00:00 2001 From: Stuart Breckenridge Date: Mon, 8 Mar 2021 10:06:30 +0800 Subject: [PATCH 33/67] fixes #2823 --- .../Detail/DetailWebViewController.swift | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/Mac/MainWindow/Detail/DetailWebViewController.swift b/Mac/MainWindow/Detail/DetailWebViewController.swift index 5c6f9a5ed..674067a4f 100644 --- a/Mac/MainWindow/Detail/DetailWebViewController.swift +++ b/Mac/MainWindow/Detail/DetailWebViewController.swift @@ -116,7 +116,7 @@ final class DetailWebViewController: NSViewController, WKUIDelegate { NotificationCenter.default.addObserver(self, selector: #selector(avatarDidBecomeAvailable(_:)), name: .AvatarDidBecomeAvailable, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(faviconDidBecomeAvailable(_:)), name: .FaviconDidBecomeAvailable, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(userDefaultsDidChange(_:)), name: UserDefaults.didChangeNotification, object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(bigSurOffsetFix(_:)), name: NSWindow.didExitFullScreenNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(bigSurOffsetFix(_:)), name: NSWindow.didChangeScreenNotification, object: nil) webView.loadFileURL(ArticleRenderer.blank.url, allowingReadAccessTo: ArticleRenderer.blank.baseURL) } @@ -142,15 +142,19 @@ final class DetailWebViewController: NSViewController, WKUIDelegate { } } - /// On macOS 11, when a user exits full screen, the webview's origin.y is offset by a sizeable amount. This function adjusts the height of the window height by 1pt which puts the webview back in the correct place. This is an issue with SwiftUI and AppKit. + /// On macOS 11, when a user exits full screen or zoomed mode (full screen with menu bar showing), the webview's origin.y is offset by a sizeable amount. This function adjusts the height of the window height by 1pt which puts the webview back in the correct place. This is an issue with SwiftUI and AppKit. @objc func bigSurOffsetFix(_ note: Notification) { if #available(macOS 11, *) { - guard var frame = self.view.window?.frame else { + print(note.name) + guard var frame = view.window?.frame else { return } - frame.size = NSSize(width: self.view.window!.frame.width, height: self.view.window!.frame.height - 1) - self.view.window!.setFrame(frame, display: true) + frame.size = NSSize(width: view.window!.frame.width, height: view.window!.frame.height - 1) + view.window!.setFrame(frame, display: false) + frame.size = NSSize(width: view.window!.frame.width, height: view.window!.frame.height + 1) + view.window!.setFrame(frame, display: false) } + } // MARK: Media Functions From a59df3e6fc09496543ea568b20edaba2736fcdf2 Mon Sep 17 00:00:00 2001 From: Stuart Breckenridge Date: Mon, 8 Mar 2021 10:28:51 +0800 Subject: [PATCH 34/67] Moves frame tweaking to end of liveResize --- Mac/MainWindow/Detail/DetailWebView.swift | 13 +++++++++++++ .../Detail/DetailWebViewController.swift | 16 ---------------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/Mac/MainWindow/Detail/DetailWebView.swift b/Mac/MainWindow/Detail/DetailWebView.swift index e235b7d7b..0b4c8e873 100644 --- a/Mac/MainWindow/Detail/DetailWebView.swift +++ b/Mac/MainWindow/Detail/DetailWebView.swift @@ -53,6 +53,19 @@ final class DetailWebView: WKWebView { override func viewDidEndLiveResize() { super.viewDidEndLiveResize() evaluateJavaScript("document.body.style.overflow = 'visible';", completionHandler: nil) + + + /// On macOS 11, when a user exits full screen or zoomed mode (full screen with menu bar showing), the webview's origin.y is offset by a sizeable amount. This function adjusts the height of the window height by 1pt which puts the webview back in the correct place. This is an issue with SwiftUI and AppKit. + if #available(macOS 11, *) { + guard var frame = window?.frame else { + return + } + frame.size = NSSize(width: window!.frame.width, height: window!.frame.height - 1) + window!.setFrame(frame, display: false) + frame.size = NSSize(width: window!.frame.width, height: window!.frame.height + 1) + window!.setFrame(frame, display: false) + } + } } diff --git a/Mac/MainWindow/Detail/DetailWebViewController.swift b/Mac/MainWindow/Detail/DetailWebViewController.swift index 674067a4f..b661a3e86 100644 --- a/Mac/MainWindow/Detail/DetailWebViewController.swift +++ b/Mac/MainWindow/Detail/DetailWebViewController.swift @@ -116,7 +116,6 @@ final class DetailWebViewController: NSViewController, WKUIDelegate { NotificationCenter.default.addObserver(self, selector: #selector(avatarDidBecomeAvailable(_:)), name: .AvatarDidBecomeAvailable, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(faviconDidBecomeAvailable(_:)), name: .FaviconDidBecomeAvailable, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(userDefaultsDidChange(_:)), name: UserDefaults.didChangeNotification, object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(bigSurOffsetFix(_:)), name: NSWindow.didChangeScreenNotification, object: nil) webView.loadFileURL(ArticleRenderer.blank.url, allowingReadAccessTo: ArticleRenderer.blank.baseURL) } @@ -142,21 +141,6 @@ final class DetailWebViewController: NSViewController, WKUIDelegate { } } - /// On macOS 11, when a user exits full screen or zoomed mode (full screen with menu bar showing), the webview's origin.y is offset by a sizeable amount. This function adjusts the height of the window height by 1pt which puts the webview back in the correct place. This is an issue with SwiftUI and AppKit. - @objc func bigSurOffsetFix(_ note: Notification) { - if #available(macOS 11, *) { - print(note.name) - guard var frame = view.window?.frame else { - return - } - frame.size = NSSize(width: view.window!.frame.width, height: view.window!.frame.height - 1) - view.window!.setFrame(frame, display: false) - frame.size = NSSize(width: view.window!.frame.width, height: view.window!.frame.height + 1) - view.window!.setFrame(frame, display: false) - } - - } - // MARK: Media Functions func stopMediaPlayback() { From f630cb16dbcfd066f63db939c9366a925e2e7746 Mon Sep 17 00:00:00 2001 From: Stuart Breckenridge Date: Mon, 8 Mar 2021 10:30:58 +0800 Subject: [PATCH 35/67] comments --- Mac/MainWindow/Detail/DetailWebView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mac/MainWindow/Detail/DetailWebView.swift b/Mac/MainWindow/Detail/DetailWebView.swift index 0b4c8e873..0dde85087 100644 --- a/Mac/MainWindow/Detail/DetailWebView.swift +++ b/Mac/MainWindow/Detail/DetailWebView.swift @@ -55,7 +55,7 @@ final class DetailWebView: WKWebView { evaluateJavaScript("document.body.style.overflow = 'visible';", completionHandler: nil) - /// On macOS 11, when a user exits full screen or zoomed mode (full screen with menu bar showing), the webview's origin.y is offset by a sizeable amount. This function adjusts the height of the window height by 1pt which puts the webview back in the correct place. This is an issue with SwiftUI and AppKit. + // On macOS 11, when a user exits full screen or exits zoomed mode (full screen with menu bar showing) by disconnecting an external display, the webview's origin.y is offset by a sizeable amount. This function adjusts the height of the window height by -1pt/+1pt which puts the webview back in the correct place. This is an issue with SwiftUI and AppKit. if #available(macOS 11, *) { guard var frame = window?.frame else { return From e2f21c15c268fde877cc9c38b41cc20471ed8004 Mon Sep 17 00:00:00 2001 From: Stuart Breckenridge Date: Mon, 8 Mar 2021 14:12:32 +0800 Subject: [PATCH 36/67] formatting --- Mac/MainWindow/Detail/DetailWebView.swift | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Mac/MainWindow/Detail/DetailWebView.swift b/Mac/MainWindow/Detail/DetailWebView.swift index 0dde85087..7252adde2 100644 --- a/Mac/MainWindow/Detail/DetailWebView.swift +++ b/Mac/MainWindow/Detail/DetailWebView.swift @@ -54,8 +54,14 @@ final class DetailWebView: WKWebView { super.viewDidEndLiveResize() evaluateJavaScript("document.body.style.overflow = 'visible';", completionHandler: nil) + /* + On macOS 11, when a user exits full screen + or exits zoomed mode by disconnecting an external display + the webview's `origin.y` is offset by a sizeable amount. - // On macOS 11, when a user exits full screen or exits zoomed mode (full screen with menu bar showing) by disconnecting an external display, the webview's origin.y is offset by a sizeable amount. This function adjusts the height of the window height by -1pt/+1pt which puts the webview back in the correct place. This is an issue with SwiftUI and AppKit. + This code adjusts the height of the window by -1pt/+1pt, + which puts the webview back in the correct place. + */ if #available(macOS 11, *) { guard var frame = window?.frame else { return @@ -65,7 +71,6 @@ final class DetailWebView: WKWebView { frame.size = NSSize(width: window!.frame.width, height: window!.frame.height + 1) window!.setFrame(frame, display: false) } - } } From 2dd475e71de762f4bc93cd058395a867d41a6a15 Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Tue, 9 Mar 2021 04:23:19 -0600 Subject: [PATCH 37/67] Return to main queue after getting notified of the dispatch group completion. Fixes #2863 --- .../CloudKit/CloudKitAccountDelegate.swift | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift b/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift index 15aeebfeb..1fbc494b5 100644 --- a/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift +++ b/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift @@ -310,20 +310,22 @@ final class CloudKitAccountDelegate: AccountDelegate { } group.notify(queue: DispatchQueue.global(qos: .background)) { - guard !errorOccurred else { - self.refreshProgress.completeTask() - completion(.failure(CloudKitAccountDelegateError.unknown)) - return - } - - self.accountZone.removeFolder(folder) { result in - self.refreshProgress.completeTask() - switch result { - case .success: - account.removeFolder(folder) - completion(.success(())) - case .failure(let error): - completion(.failure(error)) + DispatchQueue.main.async { + guard !errorOccurred else { + self.refreshProgress.completeTask() + completion(.failure(CloudKitAccountDelegateError.unknown)) + return + } + + self.accountZone.removeFolder(folder) { result in + self.refreshProgress.completeTask() + switch result { + case .success: + account.removeFolder(folder) + completion(.success(())) + case .failure(let error): + completion(.failure(error)) + } } } } From 7a17c1e8aa76317eacfb40e0a2f8b28740a032a1 Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Tue, 9 Mar 2021 04:47:15 -0600 Subject: [PATCH 38/67] Validate server data before accessing it using a subscript. Fixes #2861 --- Account/Sources/Account/ReaderAPI/ReaderAPICaller.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Account/Sources/Account/ReaderAPI/ReaderAPICaller.swift b/Account/Sources/Account/ReaderAPI/ReaderAPICaller.swift index 1d4845fdb..4e9f1b0c1 100644 --- a/Account/Sources/Account/ReaderAPI/ReaderAPICaller.swift +++ b/Account/Sources/Account/ReaderAPI/ReaderAPICaller.swift @@ -117,7 +117,9 @@ final class ReaderAPICaller: NSObject { var authData: [String: String] = [:] rawData.split(separator: "\n").forEach({ (line: Substring) in let items = line.split(separator: "=").map{String($0)} - authData[items[0]] = items[1] + if items.count == 2 { + authData[items[0]] = items[1] + } }) guard let authString = authData["Auth"] else { From 97b783db38cb7b54a22421c585b397f73b293141 Mon Sep 17 00:00:00 2001 From: Andrew Brehaut Date: Thu, 11 Mar 2021 08:16:51 +1300 Subject: [PATCH 39/67] #2371 Checks footnote target before overriding browser default behavior --- Shared/Article Rendering/newsfoot.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Shared/Article Rendering/newsfoot.js b/Shared/Article Rendering/newsfoot.js index 296c74d0b..fc5b386d5 100644 --- a/Shared/Article Rendering/newsfoot.js +++ b/Shared/Article Rendering/newsfoot.js @@ -140,12 +140,17 @@ if (targetId) break; } if (targetId === undefined) return; - + + // Only override the default behaviour when we know we can find the + // target element + const targetElement = document.querySelector(`[id='${targetId}']`); + if (targetElement === null) return; + ev.preventDefault(); installContainer(ev.target); - const content = document.querySelector(`[id='${targetId}']`).innerHTML; - void new Footnote(content, ev.target); + + void new Footnote(targetElement.innerHTML, ev.target); }); // Handle clicks on the footnote reverse link From 34f00b778037e47b3b44254041d27c1e6d7e3b0b Mon Sep 17 00:00:00 2001 From: Andrew Brehaut Date: Thu, 11 Mar 2021 10:54:25 +1300 Subject: [PATCH 40/67] Update Shared/Article Rendering/newsfoot.js Good catch thanks Co-authored-by: Jed Fox --- Shared/Article Rendering/newsfoot.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Shared/Article Rendering/newsfoot.js b/Shared/Article Rendering/newsfoot.js index fc5b386d5..1a53dbe42 100644 --- a/Shared/Article Rendering/newsfoot.js +++ b/Shared/Article Rendering/newsfoot.js @@ -143,7 +143,7 @@ // Only override the default behaviour when we know we can find the // target element - const targetElement = document.querySelector(`[id='${targetId}']`); + const targetElement = document.getElementById(targetId); if (targetElement === null) return; ev.preventDefault(); From 7297fddec90059b09f2bbccb6595f7d946d626d7 Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Thu, 11 Mar 2021 19:24:06 -0600 Subject: [PATCH 41/67] Reduce block size to reduce the number of times CloudKit has to tell us to split our number of records --- .../Sources/Account/CloudKit/CloudKitSendStatusOperation.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Account/Sources/Account/CloudKit/CloudKitSendStatusOperation.swift b/Account/Sources/Account/CloudKit/CloudKitSendStatusOperation.swift index 30c983ef2..26497e916 100644 --- a/Account/Sources/Account/CloudKit/CloudKitSendStatusOperation.swift +++ b/Account/Sources/Account/CloudKit/CloudKitSendStatusOperation.swift @@ -16,7 +16,7 @@ import SyncDatabase class CloudKitSendStatusOperation: MainThreadOperation { private var log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "CloudKit") - private let blockSize = 300 + private let blockSize = 150 // MainThreadOperation public var isCanceled = false From b475aa2ca6f806a2c7912ec19ab2e6283e3fe212 Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Thu, 11 Mar 2021 19:27:11 -0600 Subject: [PATCH 42/67] Upgrade to latest RSCore --- .../project.xcworkspace/xcshareddata/swiftpm/Package.resolved | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NetNewsWire.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/NetNewsWire.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index ae2eb2544..0be93847a 100644 --- a/NetNewsWire.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/NetNewsWire.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -60,8 +60,8 @@ "repositoryURL": "https://github.com/Ranchero-Software/RSCore.git", "state": { "branch": null, - "revision": "7070f8a7f5cad5fcbe2444a4b6265af20efd85a6", - "version": "1.0.3" + "revision": "09bdc9af601af2ca6a3a72a8b3c6aec04dfdbd88", + "version": "1.0.4" } }, { From bf76cb810de74a1b34428f5302ddaddeb222fb1d Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Thu, 11 Mar 2021 19:43:05 -0600 Subject: [PATCH 43/67] Change to always copy between accounts. Fixes #2871 --- .../Sidebar/SidebarOutlineDataSource.swift | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/Mac/MainWindow/Sidebar/SidebarOutlineDataSource.swift b/Mac/MainWindow/Sidebar/SidebarOutlineDataSource.swift index 052f9bfca..4438ffd90 100644 --- a/Mac/MainWindow/Sidebar/SidebarOutlineDataSource.swift +++ b/Mac/MainWindow/Sidebar/SidebarOutlineDataSource.swift @@ -250,11 +250,7 @@ private extension SidebarOutlineDataSource { return .move } } else { - if NSApplication.shared.currentEvent?.modifierFlags.contains(.option) ?? false { - return .move - } else { - return .copy - } + return .copy } } @@ -453,11 +449,7 @@ private extension SidebarOutlineDataSource { moveWebFeedInAccount(node: node, to: parentNode) } } else { - if NSApplication.shared.currentEvent?.modifierFlags.contains(.option) ?? false { - moveWebFeedBetweenAccounts(node: node, to: parentNode) - } else { - copyWebFeedBetweenAccounts(node: node, to: parentNode) - } + copyWebFeedBetweenAccounts(node: node, to: parentNode) } } @@ -579,11 +571,7 @@ private extension SidebarOutlineDataSource { draggedNodes.forEach { node in if !sameAccount(node, parentNode) { - if NSApplication.shared.currentEvent?.modifierFlags.contains(.option) ?? false { - moveFolderBetweenAccounts(node: node, to: parentNode) - } else { - copyFolderBetweenAccounts(node: node, to: parentNode) - } + copyFolderBetweenAccounts(node: node, to: parentNode) } } From bde9aa558055a2c6742e41a4c66d8fb9c0220f81 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sat, 13 Mar 2021 11:55:29 -0800 Subject: [PATCH 44/67] Write release notes for 6.0b2. --- Technotes/ReleaseNotes-Mac.markdown | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Technotes/ReleaseNotes-Mac.markdown b/Technotes/ReleaseNotes-Mac.markdown index c3aee6cb9..31cce0656 100644 --- a/Technotes/ReleaseNotes-Mac.markdown +++ b/Technotes/ReleaseNotes-Mac.markdown @@ -1,5 +1,12 @@ # Mac Release Notes +### 6.0b2 build 6022 - 13 Mar 2021 + +Feeds list: when dragging feeds/folders from one account to another, the operation is now *always* copy, to avoid data loss due to misunderstanding that moving a feed between accounts does not move its read/starred statuses +iCloud sync: refined logic to improve performance of large uploads +Fixed a crashing bug that could happen when deleting an iCloud-synced folder +Fixed a crashing bug, triggered by bad server data, that could happen when validating credentials with syncing systems that use the Reader API + ### 6.0b1 build 6012 - 7 Mar 2021 Article view: fixed several layout edge cases, including with fullscreen From 80f79bc553a83605ca3a12adabd14cb342e45a15 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Sat, 13 Mar 2021 11:55:39 -0800 Subject: [PATCH 45/67] Bump version to 6.0b2. --- xcconfig/common/NetNewsWire_mac_target_common.xcconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xcconfig/common/NetNewsWire_mac_target_common.xcconfig b/xcconfig/common/NetNewsWire_mac_target_common.xcconfig index aa6e7d1d0..df8540584 100644 --- a/xcconfig/common/NetNewsWire_mac_target_common.xcconfig +++ b/xcconfig/common/NetNewsWire_mac_target_common.xcconfig @@ -1,6 +1,6 @@ // High Level Settings common to both the Mac application and any extensions we bundle with it -MARKETING_VERSION = 6.0b1 -CURRENT_PROJECT_VERSION = 6012 +MARKETING_VERSION = 6.0b2 +CURRENT_PROJECT_VERSION = 6022 ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; From c1a6c42bd370d800513f0afb8c6a2556218311b7 Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Sun, 14 Mar 2021 14:06:09 -0500 Subject: [PATCH 46/67] Remove Hide Unread Count preference. Fixes #2881 --- Mac/AppDefaults.swift | 10 -- Mac/AppDelegate.swift | 2 +- Mac/Base.lproj/Preferences.storyboard | 109 +++++++----------- .../GeneralPrefencesViewController.swift | 46 -------- 4 files changed, 43 insertions(+), 124 deletions(-) diff --git a/Mac/AppDefaults.swift b/Mac/AppDefaults.swift index f40011bbb..00fee7fb7 100644 --- a/Mac/AppDefaults.swift +++ b/Mac/AppDefaults.swift @@ -43,7 +43,6 @@ final class AppDefaults { static let showDebugMenu = "ShowDebugMenu" static let timelineShowsSeparators = "CorreiaSeparators" static let showTitleOnMainWindow = "KafasisTitleMode" - static let hideDockUnreadCount = "JustinMillerHideDockUnreadCount" static let feedDoubleClickMarkAsRead = "GruberFeedDoubleClickMarkAsRead" #if !MAC_APP_STORE @@ -195,15 +194,6 @@ final class AppDefaults { return AppDefaults.bool(for: Key.showDebugMenu) } - var hideDockUnreadCount: Bool { - get { - return AppDefaults.bool(for: Key.hideDockUnreadCount) - } - set { - AppDefaults.setBool(for: Key.hideDockUnreadCount, newValue) - } - } - var feedDoubleClickMarkAsRead: Bool { get { return AppDefaults.bool(for: Key.feedDoubleClickMarkAsRead) diff --git a/Mac/AppDelegate.swift b/Mac/AppDelegate.swift index b5e34b3b4..969aee810 100644 --- a/Mac/AppDelegate.swift +++ b/Mac/AppDelegate.swift @@ -491,7 +491,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations, // MARK: - Dock Badge @objc func updateDockBadge() { - let label = unreadCount > 0 && !AppDefaults.shared.hideDockUnreadCount ? "\(unreadCount)" : "" + let label = unreadCount > 0 ? "\(unreadCount)" : "" NSApplication.shared.dockTile.badgeLabel = label } diff --git a/Mac/Base.lproj/Preferences.storyboard b/Mac/Base.lproj/Preferences.storyboard index 25b430794..ddd693d02 100644 --- a/Mac/Base.lproj/Preferences.storyboard +++ b/Mac/Base.lproj/Preferences.storyboard @@ -31,15 +31,15 @@ - - + + - + - + @@ -47,7 +47,7 @@ - + @@ -76,10 +76,10 @@ - + - + @@ -87,7 +87,7 @@ - + @@ -102,7 +102,7 @@ - + @@ -130,10 +130,10 @@ - + - + @@ -141,7 +141,7 @@ - + @@ -175,37 +175,16 @@ - - - - - - - - - - - - @@ -219,18 +198,15 @@ - - - - + @@ -243,7 +219,6 @@ - @@ -256,14 +231,14 @@ - + - + - + @@ -271,7 +246,7 @@