diff --git a/Mac/AppAssets.swift b/Mac/AppAssets.swift index d732f28d8..6af2d6a6a 100644 --- a/Mac/AppAssets.swift +++ b/Mac/AppAssets.swift @@ -167,7 +167,10 @@ struct AppAssets { }() static var preferencesToolbarExtensionsImage: RSImage = { - return RSImage(named: "preferencesToolbarExtensions")! + if #unavailable(macOS 12.0) { + return RSImage(named: "preferencesToolbarExtensions")! + } + return NSImage(systemSymbolName: "puzzlepiece.extension", accessibilityDescription: nil)! }() static var preferencesToolbarGeneralImage: RSImage = { diff --git a/Mac/MainWindow/About/AboutHTML.swift b/Mac/MainWindow/About/AboutHTML.swift new file mode 100644 index 000000000..1c5cd0433 --- /dev/null +++ b/Mac/MainWindow/About/AboutHTML.swift @@ -0,0 +1,64 @@ +// +// AboutHTML.swift +// NetNewsWire +// +// Created by Stuart Breckenridge on 28/05/2023. +// Copyright © 2023 Ranchero Software. All rights reserved. +// + +import Html + +@available(macOS 12, *) +struct AboutHTML: LoadableAboutData { + + private func stylesheet() -> StaticString { + """ + body { + margin: 2em; + color: #333333; + background-color: white; + line-height: 1.1em; + font-family: -apple-system; + text-align: center; + font-size: 12px; + } + + h3 { padding-top: 10px; padding-bottom: 8px; } + @media (prefers-color-scheme: dark) { + body { + color: white; + background-color: #333333; + } + + a { color: rgba(94, 158, 244, 1); } + } + """ + } + + private func document() -> Node { + return Node.document( + .html( + .head( + .style(safe: stylesheet()) + ), + .body( + Node.h3(.text(NSLocalizedString("label.text.primary-contributors", comment: "Primary Contributors"))), + Node.fragment(about.PrimaryContributors.map { .p(.a(attributes: [.href($0.url ?? "")], "\($0.name)")) }), + Node.h3(.text(NSLocalizedString("label.text.additional-contributors", comment: "Additional Contributors"))), + Node.fragment(about.AdditionalContributors.map { .p(.a(attributes: [.href($0.url ?? "")], "\($0.name)")) }), + Node.h3(.text(NSLocalizedString("label.text.thanks", comment: "Thanks"))), + Node.raw(NSLocalizedString("label.text.thanks-details", comment: "Thanks details")) + + ) + ) + ) + } + + func renderedDocument() -> String { + return render(document()) + } +} + + + + diff --git a/Mac/MainWindow/About/AboutNetNewsWireView.swift b/Mac/MainWindow/About/AboutNetNewsWireView.swift deleted file mode 100644 index 371dce693..000000000 --- a/Mac/MainWindow/About/AboutNetNewsWireView.swift +++ /dev/null @@ -1,55 +0,0 @@ -// -// AboutNetNewsWireView.swift -// NetNewsWire -// -// Created by Stuart Breckenridge on 03/10/2022. -// Copyright © 2022 Ranchero Software. All rights reserved. -// - -import SwiftUI - -@available(macOS 12, *) -struct AboutNetNewsWireView: View { - var body: some View { - HStack { - Spacer() - VStack(spacing: 8) { - Spacer() - - Image("About") - .resizable() - .frame(width: 75, height: 75) - - Text(verbatim: "NetNewsWire") - .font(.headline) - - Text("\(Bundle.main.versionNumber) (\(Bundle.main.buildNumber))") - .foregroundColor(.secondary) - .font(.callout) - - Text("label.text.netnewswire-byline", comment: "By Brent Simmons and the NetNewsWire team.") - .font(.subheadline) - - Text("label.markdown.netnewswire-website", comment: "Markdown formatted link to netnewswire.com") - .font(.callout) - - Spacer() - - Text(verbatim: "Copyright © Brent Simmons 2002 - \(Calendar.current.component(.year, from: .now))") - .font(.callout) - .foregroundColor(.secondary) - .padding(.bottom) - } - Spacer() - } - .multilineTextAlignment(.center) - .frame(width: 400, height: 400) - } -} - -@available(macOS 12, *) -struct AboutNetNewsWireView_Previews: PreviewProvider { - static var previews: some View { - AboutNetNewsWireView() - } -} diff --git a/Mac/MainWindow/About/AboutNewNewsWireView.swift b/Mac/MainWindow/About/AboutNewNewsWireView.swift new file mode 100644 index 000000000..30bcb9e18 --- /dev/null +++ b/Mac/MainWindow/About/AboutNewNewsWireView.swift @@ -0,0 +1,93 @@ +// +// AboutNewNewsWireView.swift +// NetNewsWire +// +// Created by Stuart Breckenridge on 03/10/2022. +// Copyright © 2022 Ranchero Software. All rights reserved. +// + +import SwiftUI +import WebKit +import Html + +@available(macOS 12, *) +fileprivate struct WebView: NSViewRepresentable { + + var htmlString: String + + func makeNSView(context: Context) -> DetailWebView { + let view = DetailWebView() + view.loadHTMLString(htmlString, baseURL: nil) + return view + } + + func updateNSView(_ webView: DetailWebView, context: Context) { + webView.navigationDelegate = context.coordinator + } + + func makeCoordinator() -> Coordinator { + Coordinator(self) + } + + class Coordinator: NSObject, WKNavigationDelegate { + + var parent: WebView! + + init(_ parent: WebView) { + self.parent = parent + } + + func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { + if navigationAction.navigationType == .linkActivated { + if let url = navigationAction.request.url { + Task { @MainActor in Browser.open(url.absoluteString) } + } + decisionHandler(.cancel) + return + } + decisionHandler(.allow) + } + } +} + +@available(macOS 12, *) +struct AboutNewNewsWireView: View, LoadableAboutData { + var body: some View { + VStack(spacing: 4) { + + Image("About") + .resizable() + .frame(width: 70, height: 70) + .padding(.top) + + Text(verbatim: "NetNewsWire") + .font(.title3) + .bold() + + Text("\(Bundle.main.versionNumber) (\(Bundle.main.buildNumber))") + .font(.body) + .padding(.bottom) + + WebView(htmlString: AboutHTML().renderedDocument()) + .overlay(Divider(), alignment: .top) + .overlay(Divider(), alignment: .bottom) + + HStack(alignment: .center) { + Spacer() + Text(verbatim: "Copyright © Brent Simmons 2002 - \(Calendar.current.component(.year, from: .now))") + .font(.caption2) + .padding(.bottom, 6) + .padding(.top, 2) + Spacer() + } + } + .frame(width: 425, height: 550) + } +} + +@available(macOS 12, *) +struct AboutNetNewsWireView_Previews: PreviewProvider { + static var previews: some View { + AboutNewNewsWireView() + } +} diff --git a/Mac/MainWindow/About/AboutWindowController.swift b/Mac/MainWindow/About/AboutWindowController.swift index 9fbe83ac2..341408dfd 100644 --- a/Mac/MainWindow/About/AboutWindowController.swift +++ b/Mac/MainWindow/About/AboutWindowController.swift @@ -10,10 +10,6 @@ import AppKit import SwiftUI import RSCore -extension NSToolbarItem.Identifier { - static let aboutGroup = NSToolbarItem.Identifier("about.toolbar.group") -} - extension NSUserInterfaceItemIdentifier { static let aboutNetNewsWire = NSUserInterfaceItemIdentifier("about.netnewswire") } @@ -21,19 +17,19 @@ extension NSUserInterfaceItemIdentifier { // MARK: - AboutWindowController @available(macOS 12, *) -class AboutWindowController: NSWindowController, NSToolbarDelegate { +class AboutWindowController: NSWindowController { var hostingController: AboutHostingController override init(window: NSWindow?) { - self.hostingController = AboutHostingController(rootView: AnyView(AboutNetNewsWireView())) + self.hostingController = AboutHostingController(rootView: AnyView(AboutNewNewsWireView())) super.init(window: window) let window = NSWindow(contentViewController: hostingController) window.identifier = .aboutNetNewsWire window.standardWindowButton(.zoomButton)?.isEnabled = false + window.standardWindowButton(.miniaturizeButton)?.isEnabled = false window.titleVisibility = .hidden self.window = window - self.hostingController.configureToolbar() } required init?(coder: NSCoder) { @@ -49,17 +45,7 @@ class AboutWindowController: NSWindowController, NSToolbarDelegate { // MARK: - AboutHostingController @available(macOS 12, *) -class AboutHostingController: NSHostingController, NSToolbarDelegate { - - private lazy var segmentedControl: NSSegmentedControl = { - let control = NSSegmentedControl(labels: ["About", "Credits"], - trackingMode: .selectOne, - target: self, - action: #selector(segmentedControlSelectionChanged(_:))) - control.segmentCount = 2 - control.setSelected(true, forSegment: 0) - return control - }() +class AboutHostingController: NSHostingController { override init(rootView: AnyView) { super.init(rootView: rootView) @@ -68,63 +54,6 @@ class AboutHostingController: NSHostingController, NSToolbarDelegate { @MainActor required dynamic init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } - - public func configureToolbar() { - let toolbar = NSToolbar(identifier: NSToolbar.Identifier("netnewswire.about.toolbar")) - toolbar.delegate = self - toolbar.autosavesConfiguration = false - toolbar.allowsUserCustomization = false - view.window?.toolbar = toolbar - view.window?.toolbarStyle = .unified - toolbar.insertItem(withItemIdentifier: .flexibleSpace, at: 0) - toolbar.insertItem(withItemIdentifier: .flexibleSpace, at: 2) - } - - // MARK: NSToolbarDelegate - - func toolbar(_ toolbar: NSToolbar, itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier, willBeInsertedIntoToolbar flag: Bool) -> NSToolbarItem? { - switch itemIdentifier { - - case .aboutGroup: - let toolbarItem = NSToolbarItem(itemIdentifier: .aboutGroup) - toolbarItem.view = segmentedControl - toolbarItem.autovalidates = true - return toolbarItem - default: - return nil - } - } - - func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] { - return [.aboutGroup] - } - - func toolbarWillAddItem(_ notification: Notification) { - // - } - - func toolbarDidRemoveItem(_ notification: Notification) { - // - } - - func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] { - return [.aboutGroup] - } - - func toolbarSelectableItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] { - return [] - } - - // MARK: - Target/Action - @objc - func segmentedControlSelectionChanged(_ sender: NSSegmentedControl) { - if sender.selectedSegment == 0 { - rootView = AnyView(AboutNetNewsWireView()) - } else { - rootView = AnyView(CreditsNetNewsWireView()) - } - } - } diff --git a/Mac/MainWindow/About/CreditsNetNewsWireView.swift b/Mac/MainWindow/About/CreditsNetNewsWireView.swift deleted file mode 100644 index f72318696..000000000 --- a/Mac/MainWindow/About/CreditsNetNewsWireView.swift +++ /dev/null @@ -1,82 +0,0 @@ -// -// CreditsNetNewsWireView.swift -// NetNewsWire -// -// Created by Stuart Breckenridge on 03/10/2022. -// Copyright © 2022 Ranchero Software. All rights reserved. -// - -import SwiftUI - -@available(macOS 12, *) -struct CreditsNetNewsWireView: View, LoadableAboutData { - var body: some View { - ScrollView(.vertical, showsIndicators: false) { - Spacer() - .frame(height: 12) - Section("Primary Contributors") { - GroupBox { - ForEach(0.. some View { - HStack { - Text(appCredit.name) - Spacer() - if let role = appCredit.role { - Text(role) - .foregroundColor(.secondary) - } - Image(systemName: "info.circle") - .foregroundColor(.secondary) - } - .onTapGesture { - guard let url = appCredit.url else { return } - if let _ = URL(string: url) { - Task { @MainActor in - Browser.open(url, inBackground: false) - } - } - } - } -} - -@available(macOS 12, *) -struct CreditsNetNewsWireView_Previews: PreviewProvider { - static var previews: some View { - CreditsNetNewsWireView() - } -} diff --git a/Mac/Resources/en-GB.lproj/Localizable.strings b/Mac/Resources/en-GB.lproj/Localizable.strings index a15770112..20a466e6d 100644 --- a/Mac/Resources/en-GB.lproj/Localizable.strings +++ b/Mac/Resources/en-GB.lproj/Localizable.strings @@ -454,6 +454,12 @@ /* You've added all available extensions. */ "label.text.added-all-extensions" = "You've added all available extensions."; +/* Primary Contributors */ +"label.text.primary-contributors" = "Primary Contributors"; + +/* Additional Contributors */ +"label.text.additional-contributors" = "Additional Contributors"; + /* Article */ "label.text.article" = "Article"; @@ -586,6 +592,15 @@ /* Subreddit */ "label.text.subreddit" = "Subreddit"; +/* Thanks */ +"label.text.thanks" = "Thanks"; + +/* Thanks - Dedication */ +"label.text.thanks-details" = " +

Thanks to Sheila and my family; thanks to my friends in Seattle and around the globe; thanks to the ever-patient and ever-awesome NetNewsWire beta testers.

+

Thanks to Gus Mueller for FMDB by Flying Meat Software. Thanks to GitHub and Slack for making open source collaboration easy and fun. Thanks to Ben Ubois at Feedbin for all the extra help with syncing and article rendering — and for hosting the server for the Reader view.

+

NetNewsWire 6 is dedicated to everyone working to save democracy around the world.

"; + /* Built-in */ "label.text.themes-builtin" = "Built-in Themes"; diff --git a/Mac/Resources/en.lproj/Localizable.strings b/Mac/Resources/en.lproj/Localizable.strings index cba3a859f..729706083 100644 --- a/Mac/Resources/en.lproj/Localizable.strings +++ b/Mac/Resources/en.lproj/Localizable.strings @@ -447,6 +447,12 @@ /* You've added all available extensions. */ "label.text.added-all-extensions" = "You've added all available extensions."; +/* Primary Contributors */ +"label.text.primary-contributors" = "Primary Contributors"; + +/* Additional Contributors */ +"label.text.additional-contributors" = "Additional Contributors"; + /* Article */ "label.text.article" = "Article"; @@ -579,6 +585,15 @@ /* Subreddit */ "label.text.subreddit" = "Subreddit"; +/* Thanks */ +"label.text.thanks" = "Thanks"; + +/* Thanks - Dedication */ +"label.text.thanks-details" = " +

Thanks to Sheila and my family; thanks to my friends in Seattle and around the globe; thanks to the ever-patient and ever-awesome NetNewsWire beta testers.

+

Thanks to Gus Mueller for FMDB by Flying Meat Software. Thanks to GitHub and Slack for making open source collaboration easy and fun. Thanks to Ben Ubois at Feedbin for all the extra help with syncing and article rendering — and for hosting the server for the Reader view.

+

NetNewsWire 6 is dedicated to everyone working to save democracy around the world.

"; + /* Built-in */ "label.text.themes-builtin" = "Built-in Themes"; diff --git a/NetNewsWire.xcodeproj/project.pbxproj b/NetNewsWire.xcodeproj/project.pbxproj index e5bdab5e6..9303cc15b 100644 --- a/NetNewsWire.xcodeproj/project.pbxproj +++ b/NetNewsWire.xcodeproj/project.pbxproj @@ -826,6 +826,8 @@ DF5125032A23116B00BBAB1F /* MasterTimelineTitleView.xib in Resources */ = {isa = PBXBuildFile; fileRef = DF5125052A23116B00BBAB1F /* MasterTimelineTitleView.xib */; }; DF5125082A23118300BBAB1F /* Add.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DF51250A2A23118300BBAB1F /* Add.storyboard */; }; DF51250D2A23119800BBAB1F /* AddFeedSelectFolderTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = DF51250F2A23119800BBAB1F /* AddFeedSelectFolderTableViewCell.xib */; }; + DF5124CA2A22D5FA00BBAB1F /* Html in Frameworks */ = {isa = PBXBuildFile; productRef = DF5124C92A22D5FA00BBAB1F /* Html */; }; + DF5124CC2A22D62600BBAB1F /* AboutHTML.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF5124CB2A22D62600BBAB1F /* AboutHTML.swift */; }; DF59F072292085B800ACD33D /* ColorPaletteSelectorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF59F071292085B800ACD33D /* ColorPaletteSelectorView.swift */; }; DF59F0742920DB5100ACD33D /* AccountsManagementView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF59F0732920DB5100ACD33D /* AccountsManagementView.swift */; }; DF5AD10128D6922200CA3BF7 /* SmartFeedSummaryWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1768144D2564BCE000D98635 /* SmartFeedSummaryWidget.swift */; }; @@ -869,8 +871,7 @@ DFC14F0F28EA55BD00F6EE86 /* AboutWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFC14F0E28EA55BD00F6EE86 /* AboutWindowController.swift */; }; DFC14F1228EA5DC500F6EE86 /* AboutData.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF790D6128E990A900455FC7 /* AboutData.swift */; }; DFC14F1328EA677C00F6EE86 /* Bundle-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51F85BF42273625800C787DC /* Bundle-Extensions.swift */; }; - DFC14F1528EB177000F6EE86 /* AboutNetNewsWireView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFC14F1428EB177000F6EE86 /* AboutNetNewsWireView.swift */; }; - DFC14F1728EB17A800F6EE86 /* CreditsNetNewsWireView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFC14F1628EB17A800F6EE86 /* CreditsNetNewsWireView.swift */; }; + DFC14F1728EB17A800F6EE86 /* AboutNewNewsWireView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFC14F1628EB17A800F6EE86 /* AboutNewNewsWireView.swift */; }; DFCE4F9128EF26F100405869 /* About.plist in Resources */ = {isa = PBXBuildFile; fileRef = DFCE4F9028EF26F000405869 /* About.plist */; }; DFCE4F9228EF26F100405869 /* About.plist in Resources */ = {isa = PBXBuildFile; fileRef = DFCE4F9028EF26F000405869 /* About.plist */; }; DFCE4F9428EF278300405869 /* Thanks.md in Resources */ = {isa = PBXBuildFile; fileRef = DFCE4F9328EF278300405869 /* Thanks.md */; }; @@ -1607,6 +1608,7 @@ DF51250C2A23118700BBAB1F /* en-GB */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "en-GB"; path = "en-GB.lproj/Add.strings"; sourceTree = ""; }; DF51250E2A23119800BBAB1F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/AddFeedSelectFolderTableViewCell.xib; sourceTree = ""; }; DF5125112A23119B00BBAB1F /* en-GB */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "en-GB"; path = "en-GB.lproj/AddFeedSelectFolderTableViewCell.strings"; sourceTree = ""; }; + DF5124CB2A22D62600BBAB1F /* AboutHTML.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutHTML.swift; sourceTree = ""; }; DF59F071292085B800ACD33D /* ColorPaletteSelectorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPaletteSelectorView.swift; sourceTree = ""; }; DF59F0732920DB5100ACD33D /* AccountsManagementView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountsManagementView.swift; sourceTree = ""; }; DF6DE5092965907A002EC085 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; @@ -1661,8 +1663,7 @@ DFBB4EAB2951BC0200639228 /* NNWThemeDocument.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NNWThemeDocument.swift; sourceTree = ""; }; DFBB4EAF2951BCAC00639228 /* ArticleThemeManagerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleThemeManagerView.swift; sourceTree = ""; }; DFC14F0E28EA55BD00F6EE86 /* AboutWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutWindowController.swift; sourceTree = ""; }; - DFC14F1428EB177000F6EE86 /* AboutNetNewsWireView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutNetNewsWireView.swift; sourceTree = ""; }; - DFC14F1628EB17A800F6EE86 /* CreditsNetNewsWireView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreditsNetNewsWireView.swift; sourceTree = ""; }; + DFC14F1628EB17A800F6EE86 /* AboutNewNewsWireView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutNewNewsWireView.swift; sourceTree = ""; }; DFCE4F9028EF26F000405869 /* About.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = About.plist; sourceTree = ""; }; DFCE4F9328EF278300405869 /* Thanks.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = Thanks.md; sourceTree = ""; }; DFD406F4291F79C900C02962 /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = ""; }; @@ -1802,6 +1803,7 @@ 51C4CFF624D37DD500AF9874 /* Secrets in Frameworks */, 51A737AE24DB19730015FA66 /* RSCore in Frameworks */, 51A737C824DB19CC0015FA66 /* RSParser in Frameworks */, + DF5124CA2A22D5FA00BBAB1F /* Html in Frameworks */, 179C39EA26F76B0500D4E741 /* Zip in Frameworks */, 51E4DAED2425F6940091EB5B /* CloudKit.framework in Frameworks */, 514C16E124D2EF38009A3AFA /* RSCoreResources in Frameworks */, @@ -3010,8 +3012,8 @@ isa = PBXGroup; children = ( DFC14F0E28EA55BD00F6EE86 /* AboutWindowController.swift */, - DFC14F1428EB177000F6EE86 /* AboutNetNewsWireView.swift */, - DFC14F1628EB17A800F6EE86 /* CreditsNetNewsWireView.swift */, + DFC14F1628EB17A800F6EE86 /* AboutNewNewsWireView.swift */, + DF5124CB2A22D62600BBAB1F /* AboutHTML.swift */, ); path = About; sourceTree = ""; @@ -3306,6 +3308,7 @@ 513277602590FC640064F1E7 /* ArticlesDatabase */, 513277632590FC640064F1E7 /* SyncDatabase */, 179C39E926F76B0500D4E741 /* Zip */, + DF5124C92A22D5FA00BBAB1F /* Html */, ); productName = NetNewsWire; productReference = 849C64601ED37A5D003D8FC0 /* NetNewsWire.app */; @@ -3426,6 +3429,7 @@ 17192AD82567B3D500AAEACA /* XCRemoteSwiftPackageReference "Sparkle-Binary" */, 519CA8E325841DB700EB079A /* XCRemoteSwiftPackageReference "plcrashreporter" */, 179D280926F6F93D003B2E0A /* XCRemoteSwiftPackageReference "Zip" */, + DF5124C82A22D5FA00BBAB1F /* XCRemoteSwiftPackageReference "swift-html" */, ); productRefGroup = 849C64611ED37A5D003D8FC0 /* Products */; projectDirPath = ""; @@ -4472,6 +4476,7 @@ 841ABA5E20145E9200980E11 /* FolderInspectorViewController.swift in Sources */, 84DEE56522C32CA4005FC42C /* SmartFeedDelegate.swift in Sources */, 845213231FCA5B11003B6E93 /* ImageDownloader.swift in Sources */, + DF5124CC2A22D62600BBAB1F /* AboutHTML.swift in Sources */, 51FA73B72332D5F70090D516 /* LegacyArticleExtractorButton.swift in Sources */, 849A97431ED9EAA9007D329B /* AddFolderWindowController.swift in Sources */, 8405DDA522168C62008CE1BF /* TimelineContainerViewController.swift in Sources */, @@ -4481,7 +4486,6 @@ 849A97801ED9EC42007D329B /* DetailViewController.swift in Sources */, 173A64172547BE0900267F6E /* AccountType+Helpers.swift in Sources */, 518C3193237B00D9004D740F /* DetailIconSchemeHandler.swift in Sources */, - DFC14F1528EB177000F6EE86 /* AboutNetNewsWireView.swift in Sources */, 84C9FC6722629B9000D921D6 /* AppDelegate.swift in Sources */, 510C417F24E5D1AE008226FD /* ExtensionContainersFile.swift in Sources */, 84C9FC7A22629E1200D921D6 /* PreferencesTableViewBackgroundView.swift in Sources */, @@ -4489,7 +4493,7 @@ DFC14F1328EA677C00F6EE86 /* Bundle-Extensions.swift in Sources */, 8426119E1FCB6ED40086A189 /* HTMLMetadataDownloader.swift in Sources */, 849A976E1ED9EBC8007D329B /* TimelineViewController.swift in Sources */, - DFC14F1728EB17A800F6EE86 /* CreditsNetNewsWireView.swift in Sources */, + DFC14F1728EB17A800F6EE86 /* AboutNewNewsWireView.swift in Sources */, 5154368B229404D1005E1CDF /* FaviconGenerator.swift in Sources */, 5183CCE6226F4E110010922C /* RefreshInterval.swift in Sources */, 849A97771ED9EC04007D329B /* TimelineCellData.swift in Sources */, @@ -5368,6 +5372,14 @@ minimumVersion = 1.0.0; }; }; + DF5124C82A22D5FA00BBAB1F /* XCRemoteSwiftPackageReference "swift-html" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/pointfreeco/swift-html.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 0.4.0; + }; + }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ @@ -5602,6 +5614,11 @@ package = 5102AE4324D17E820050839C /* XCRemoteSwiftPackageReference "RSCore" */; productName = RSCore; }; + DF5124C92A22D5FA00BBAB1F /* Html */ = { + isa = XCSwiftPackageProductDependency; + package = DF5124C82A22D5FA00BBAB1F /* XCRemoteSwiftPackageReference "swift-html" */; + productName = Html; + }; /* End XCSwiftPackageProductDependency section */ }; rootObject = 849C64581ED37A5D003D8FC0 /* Project object */; diff --git a/NetNewsWire.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/NetNewsWire.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 89207c710..063bafc61 100644 --- a/NetNewsWire.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/NetNewsWire.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -109,6 +109,24 @@ "version": "2.0.1" } }, + { + "package": "swift-html", + "repositoryURL": "https://github.com/pointfreeco/swift-html.git", + "state": { + "branch": null, + "revision": "f53c38c4b841841f36afa1866093c908cadaa736", + "version": "0.4.0" + } + }, + { + "package": "swift-snapshot-testing", + "repositoryURL": "https://github.com/pointfreeco/swift-snapshot-testing.git", + "state": { + "branch": null, + "revision": "cef5b3f6f11781dd4591bdd1dd0a3d22bd609334", + "version": "1.11.0" + } + }, { "package": "Swifter", "repositoryURL": "https://github.com/httpswift/swifter.git", diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/Contents.json b/Widget/Assets.xcassets/AppIcon.appiconset/Contents.json index 8fd2ff09d..6201b3b63 100644 --- a/Widget/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/Widget/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,109 +1,109 @@ { "images" : [ { - "filename" : "icon-41.png", + "filename" : "Icon_20x20@2x.png", "idiom" : "iphone", "scale" : "2x", "size" : "20x20" }, { - "filename" : "icon-60.png", + "filename" : "Icon_20x20@3x.png", "idiom" : "iphone", "scale" : "3x", "size" : "20x20" }, { - "filename" : "icon-58.png", + "filename" : "Icon_29x29@2x.png", "idiom" : "iphone", "scale" : "2x", "size" : "29x29" }, { - "filename" : "icon-87.png", + "filename" : "Icon_29x29@3x.png", "idiom" : "iphone", "scale" : "3x", "size" : "29x29" }, { - "filename" : "icon-80.png", + "filename" : "Icon_40x40@2x.png", "idiom" : "iphone", "scale" : "2x", "size" : "40x40" }, { - "filename" : "icon-121.png", + "filename" : "Icon_40x40@3x.png", "idiom" : "iphone", "scale" : "3x", "size" : "40x40" }, { - "filename" : "icon-120.png", + "filename" : "Icon_60x60@2x.png", "idiom" : "iphone", "scale" : "2x", "size" : "60x60" }, { - "filename" : "icon-180.png", + "filename" : "Icon_60x60@3x.png", "idiom" : "iphone", "scale" : "3x", "size" : "60x60" }, { - "filename" : "icon-20.png", + "filename" : "Icon_20x20@2x 1.png", "idiom" : "ipad", "scale" : "1x", "size" : "20x20" }, { - "filename" : "icon-42.png", + "filename" : "Icon_20x20@2x 2.png", "idiom" : "ipad", "scale" : "2x", "size" : "20x20" }, { - "filename" : "icon-29.png", + "filename" : "Icon_29x29@2x 1.png", "idiom" : "ipad", "scale" : "1x", "size" : "29x29" }, { - "filename" : "icon-59.png", + "filename" : "Icon_29x29@2x 2.png", "idiom" : "ipad", "scale" : "2x", "size" : "29x29" }, { - "filename" : "icon-40.png", + "filename" : "Icon_20x20@2x 3.png", "idiom" : "ipad", "scale" : "1x", "size" : "40x40" }, { - "filename" : "icon-81.png", + "filename" : "Icon_40x40@2x 1.png", "idiom" : "ipad", "scale" : "2x", "size" : "40x40" }, { - "filename" : "icon-76.png", + "filename" : "Icon_76x76@2x 1.png", "idiom" : "ipad", "scale" : "1x", "size" : "76x76" }, { - "filename" : "icon-152.png", + "filename" : "Icon_76x76@2x.png", "idiom" : "ipad", "scale" : "2x", "size" : "76x76" }, { - "filename" : "icon-167.png", + "filename" : "Icon_83.5x83.5@2x.png", "idiom" : "ipad", "scale" : "2x", "size" : "83.5x83.5" }, { - "filename" : "icon-1024.png", + "filename" : "Icon_1024x1024.png", "idiom" : "ios-marketing", "scale" : "1x", "size" : "1024x1024" diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/Icon_1024x1024.png b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_1024x1024.png new file mode 100644 index 000000000..c23104e9b Binary files /dev/null and b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_1024x1024.png differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/Icon_20x20@2x 1.png b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_20x20@2x 1.png new file mode 100644 index 000000000..48c5411af Binary files /dev/null and b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_20x20@2x 1.png differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/Icon_20x20@2x 2.png b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_20x20@2x 2.png new file mode 100644 index 000000000..1dadf1062 Binary files /dev/null and b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_20x20@2x 2.png differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/Icon_20x20@2x 3.png b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_20x20@2x 3.png new file mode 100644 index 000000000..1dadf1062 Binary files /dev/null and b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_20x20@2x 3.png differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/Icon_20x20@2x.png b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_20x20@2x.png new file mode 100644 index 000000000..1dadf1062 Binary files /dev/null and b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_20x20@2x.png differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/Icon_20x20@3x.png b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_20x20@3x.png new file mode 100644 index 000000000..05b3f4a70 Binary files /dev/null and b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_20x20@3x.png differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/Icon_29x29@2x 1.png b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_29x29@2x 1.png new file mode 100644 index 000000000..670ae67ad Binary files /dev/null and b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_29x29@2x 1.png differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/Icon_29x29@2x 2.png b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_29x29@2x 2.png new file mode 100644 index 000000000..b9fc738a9 Binary files /dev/null and b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_29x29@2x 2.png differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/Icon_29x29@2x.png b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_29x29@2x.png new file mode 100644 index 000000000..b9fc738a9 Binary files /dev/null and b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_29x29@2x.png differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/Icon_29x29@3x.png b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_29x29@3x.png new file mode 100644 index 000000000..79e1a4011 Binary files /dev/null and b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_29x29@3x.png differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/Icon_40x40@2x 1.png b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_40x40@2x 1.png new file mode 100644 index 000000000..44fd5c3a1 Binary files /dev/null and b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_40x40@2x 1.png differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/Icon_40x40@2x.png b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_40x40@2x.png new file mode 100644 index 000000000..44fd5c3a1 Binary files /dev/null and b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_40x40@2x.png differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/Icon_40x40@3x.png b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_40x40@3x.png new file mode 100644 index 000000000..373ea7096 Binary files /dev/null and b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_40x40@3x.png differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/Icon_60x60@2x.png b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_60x60@2x.png new file mode 100644 index 000000000..a137eda8b Binary files /dev/null and b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_60x60@2x.png differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/Icon_60x60@3x.png b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_60x60@3x.png new file mode 100644 index 000000000..d9a7facab Binary files /dev/null and b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_60x60@3x.png differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/Icon_76x76@2x 1.png b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_76x76@2x 1.png new file mode 100644 index 000000000..371b11cef Binary files /dev/null and b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_76x76@2x 1.png differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/Icon_76x76@2x.png b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_76x76@2x.png new file mode 100644 index 000000000..94125bb6f Binary files /dev/null and b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_76x76@2x.png differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/Icon_83.5x83.5@2x.png b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_83.5x83.5@2x.png new file mode 100644 index 000000000..7d7cb5a2e Binary files /dev/null and b/Widget/Assets.xcassets/AppIcon.appiconset/Icon_83.5x83.5@2x.png differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/icon-1024.png b/Widget/Assets.xcassets/AppIcon.appiconset/icon-1024.png deleted file mode 100644 index c2bb5d540..000000000 Binary files a/Widget/Assets.xcassets/AppIcon.appiconset/icon-1024.png and /dev/null differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/icon-120.png b/Widget/Assets.xcassets/AppIcon.appiconset/icon-120.png deleted file mode 100644 index 6d1a94fd9..000000000 Binary files a/Widget/Assets.xcassets/AppIcon.appiconset/icon-120.png and /dev/null differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/icon-121.png b/Widget/Assets.xcassets/AppIcon.appiconset/icon-121.png deleted file mode 100644 index 6d1a94fd9..000000000 Binary files a/Widget/Assets.xcassets/AppIcon.appiconset/icon-121.png and /dev/null differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/icon-152.png b/Widget/Assets.xcassets/AppIcon.appiconset/icon-152.png deleted file mode 100644 index b217d09c4..000000000 Binary files a/Widget/Assets.xcassets/AppIcon.appiconset/icon-152.png and /dev/null differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/icon-167.png b/Widget/Assets.xcassets/AppIcon.appiconset/icon-167.png deleted file mode 100644 index 4cd8fa6c0..000000000 Binary files a/Widget/Assets.xcassets/AppIcon.appiconset/icon-167.png and /dev/null differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/icon-180.png b/Widget/Assets.xcassets/AppIcon.appiconset/icon-180.png deleted file mode 100644 index 8c5c93b8c..000000000 Binary files a/Widget/Assets.xcassets/AppIcon.appiconset/icon-180.png and /dev/null differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/icon-20.png b/Widget/Assets.xcassets/AppIcon.appiconset/icon-20.png deleted file mode 100644 index 6be295367..000000000 Binary files a/Widget/Assets.xcassets/AppIcon.appiconset/icon-20.png and /dev/null differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/icon-29.png b/Widget/Assets.xcassets/AppIcon.appiconset/icon-29.png deleted file mode 100644 index c9c8ffb32..000000000 Binary files a/Widget/Assets.xcassets/AppIcon.appiconset/icon-29.png and /dev/null differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/icon-40.png b/Widget/Assets.xcassets/AppIcon.appiconset/icon-40.png deleted file mode 100644 index 180a98b25..000000000 Binary files a/Widget/Assets.xcassets/AppIcon.appiconset/icon-40.png and /dev/null differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/icon-41.png b/Widget/Assets.xcassets/AppIcon.appiconset/icon-41.png deleted file mode 100644 index 180a98b25..000000000 Binary files a/Widget/Assets.xcassets/AppIcon.appiconset/icon-41.png and /dev/null differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/icon-42.png b/Widget/Assets.xcassets/AppIcon.appiconset/icon-42.png deleted file mode 100644 index 180a98b25..000000000 Binary files a/Widget/Assets.xcassets/AppIcon.appiconset/icon-42.png and /dev/null differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/icon-58.png b/Widget/Assets.xcassets/AppIcon.appiconset/icon-58.png deleted file mode 100644 index a53d44864..000000000 Binary files a/Widget/Assets.xcassets/AppIcon.appiconset/icon-58.png and /dev/null differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/icon-59.png b/Widget/Assets.xcassets/AppIcon.appiconset/icon-59.png deleted file mode 100644 index a53d44864..000000000 Binary files a/Widget/Assets.xcassets/AppIcon.appiconset/icon-59.png and /dev/null differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/icon-60.png b/Widget/Assets.xcassets/AppIcon.appiconset/icon-60.png deleted file mode 100644 index 7a01bc978..000000000 Binary files a/Widget/Assets.xcassets/AppIcon.appiconset/icon-60.png and /dev/null differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/icon-76.png b/Widget/Assets.xcassets/AppIcon.appiconset/icon-76.png deleted file mode 100644 index 4aea101ae..000000000 Binary files a/Widget/Assets.xcassets/AppIcon.appiconset/icon-76.png and /dev/null differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/icon-80.png b/Widget/Assets.xcassets/AppIcon.appiconset/icon-80.png deleted file mode 100644 index 85289428d..000000000 Binary files a/Widget/Assets.xcassets/AppIcon.appiconset/icon-80.png and /dev/null differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/icon-81.png b/Widget/Assets.xcassets/AppIcon.appiconset/icon-81.png deleted file mode 100644 index 85289428d..000000000 Binary files a/Widget/Assets.xcassets/AppIcon.appiconset/icon-81.png and /dev/null differ diff --git a/Widget/Assets.xcassets/AppIcon.appiconset/icon-87.png b/Widget/Assets.xcassets/AppIcon.appiconset/icon-87.png deleted file mode 100644 index dd27b3ca3..000000000 Binary files a/Widget/Assets.xcassets/AppIcon.appiconset/icon-87.png and /dev/null differ diff --git a/Widget/Assets.xcassets/CornerIcon.imageset/Contents.json b/Widget/Assets.xcassets/CornerIcon.imageset/Contents.json index 16c1410ab..2a420c17d 100644 --- a/Widget/Assets.xcassets/CornerIcon.imageset/Contents.json +++ b/Widget/Assets.xcassets/CornerIcon.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "icon-1024.png", + "filename" : "Icon_1024x1024.png", "idiom" : "universal" } ], diff --git a/Widget/Assets.xcassets/CornerIcon.imageset/Icon_1024x1024.png b/Widget/Assets.xcassets/CornerIcon.imageset/Icon_1024x1024.png new file mode 100644 index 000000000..c23104e9b Binary files /dev/null and b/Widget/Assets.xcassets/CornerIcon.imageset/Icon_1024x1024.png differ diff --git a/Widget/Assets.xcassets/CornerIcon.imageset/icon-1024.png b/Widget/Assets.xcassets/CornerIcon.imageset/icon-1024.png deleted file mode 100644 index c2bb5d540..000000000 Binary files a/Widget/Assets.xcassets/CornerIcon.imageset/icon-1024.png and /dev/null differ