Application of Tracing Paper

This commit is contained in:
Stuart Breckenridge
2023-05-28 17:04:23 +08:00
parent 08d218fe27
commit 403bcc75e5
8 changed files with 128 additions and 207 deletions

View File

@@ -17,13 +17,13 @@ struct AboutHTML: LoadableAboutData {
margin: 2em;
color: #333333;
background-color: white;
line-height: 0.7em;
line-height: 1.1em;
font-family: -apple-system;
text-align: center;
font-size: 0.7em;
font-size: 12px;
}
h3 { padding-top: 10px; padding-bottom: 10px; }
h3 { padding-top: 10px; padding-bottom: 8px; }
@media (prefers-color-scheme: dark) {
body {
color: white;
@@ -45,7 +45,10 @@ struct AboutHTML: LoadableAboutData {
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.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"))
)
)
)

View File

@@ -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()
}
}

View File

@@ -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()
}
}

View File

@@ -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<AnyView>, 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<AnyView> {
override init(rootView: AnyView) {
super.init(rootView: rootView)
@@ -68,63 +54,6 @@ class AboutHostingController: NSHostingController<AnyView>, 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())
}
}
}

View File

@@ -1,63 +0,0 @@
//
// CreditsNetNewsWireView.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, *)
struct WebView: NSViewRepresentable {
var htmlString: String
func makeNSView(context: Context) -> WKWebView {
let view = WKWebView()
view.loadHTMLString(htmlString, baseURL: nil)
return view
}
func updateNSView(_ webView: WKWebView, context: Context) {
}
}
@available(macOS 12, *)
struct CreditsNetNewsWireView: View, LoadableAboutData {
var body: some View {
VStack {
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)
WebView(htmlString: AboutHTML().renderedDocument())
}
.frame(width: 500, height: 700)
}
}
@available(macOS 12, *)
struct CreditsNetNewsWireView_Previews: PreviewProvider {
static var previews: some View {
CreditsNetNewsWireView()
}
}

View File

@@ -592,6 +592,15 @@
/* Subreddit */
"label.text.subreddit" = "Subreddit";
/* Thanks */
"label.text.thanks" = "Thanks";
/* Thanks - Dedication */
"label.text.thanks-details" = "
<p>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. </p>
<p>Thanks to <a href=\"https://shapeof.com/\">Gus Mueller</a> for <a href=\"https://github.com/ccgus/fmdb\">FMDB</a> by <a href=\"http://flyingmeat.com/\">Flying Meat Software</a>. Thanks to <a href=\"https://github.com\">GitHub</a> and <a href=\"https://slack.com\">Slack</a> for making open source collaboration easy and fun. Thanks to <a href=\"https://benubois.com/\">Ben Ubois</a> at <a href=\"https://feedbin.com/\">Feedbin</a> for all the extra help with syncing and article rendering — and for <a href=\"https://feedbin.com/blog/2019/03/11/the-future-of-full-content/\">hosting the server for the Reader view</a>.</p>
<p>NetNewsWire 6 is dedicated to everyone working to save democracy around the world.</p>";
/* Built-in */
"label.text.themes-builtin" = "Built-in Themes";

View File

@@ -585,6 +585,15 @@
/* Subreddit */
"label.text.subreddit" = "Subreddit";
/* Thanks */
"label.text.thanks" = "Thanks";
/* Thanks - Dedication */
"label.text.thanks-details" = "
<p>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. </p>
<p>Thanks to <a href=\"https://shapeof.com/\">Gus Mueller</a> for <a href=\"https://github.com/ccgus/fmdb\">FMDB</a> by <a href=\"http://flyingmeat.com/\">Flying Meat Software</a>. Thanks to <a href=\"https://github.com\">GitHub</a> and <a href=\"https://slack.com\">Slack</a> for making open source collaboration easy and fun. Thanks to <a href=\"https://benubois.com/\">Ben Ubois</a> at <a href=\"https://feedbin.com/\">Feedbin</a> for all the extra help with syncing and article rendering — and for <a href=\"https://feedbin.com/blog/2019/03/11/the-future-of-full-content/\">hosting the server for the Reader view</a>.</p>
<p>NetNewsWire 6 is dedicated to everyone working to save democracy around the world.</p>";
/* Built-in */
"label.text.themes-builtin" = "Built-in Themes";

View File

@@ -871,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 */; };
@@ -1652,8 +1651,7 @@
DFBB4EAB2951BC0200639228 /* NNWThemeDocument.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NNWThemeDocument.swift; sourceTree = "<group>"; };
DFBB4EAF2951BCAC00639228 /* ArticleThemeManagerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArticleThemeManagerView.swift; sourceTree = "<group>"; };
DFC14F0E28EA55BD00F6EE86 /* AboutWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutWindowController.swift; sourceTree = "<group>"; };
DFC14F1428EB177000F6EE86 /* AboutNetNewsWireView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutNetNewsWireView.swift; sourceTree = "<group>"; };
DFC14F1628EB17A800F6EE86 /* CreditsNetNewsWireView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreditsNetNewsWireView.swift; sourceTree = "<group>"; };
DFC14F1628EB17A800F6EE86 /* AboutNewNewsWireView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutNewNewsWireView.swift; sourceTree = "<group>"; };
DFCE4F9028EF26F000405869 /* About.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = About.plist; sourceTree = "<group>"; };
DFCE4F9328EF278300405869 /* Thanks.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = Thanks.md; sourceTree = "<group>"; };
DFD406F4291F79C900C02962 /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
@@ -2714,7 +2712,6 @@
isa = PBXGroup;
children = (
849C64671ED37A5D003D8FC0 /* Assets.xcassets */,
DF5124CB2A22D62600BBAB1F /* AboutHTML.swift */,
84C9FC8922629E8F00D921D6 /* Credits.rtf */,
DF93DB2D296A319000586C0E /* Localizable.stringsdict */,
84C9FC8A22629E8F00D921D6 /* NetNewsWire.sdef */,
@@ -3011,8 +3008,8 @@
isa = PBXGroup;
children = (
DFC14F0E28EA55BD00F6EE86 /* AboutWindowController.swift */,
DFC14F1428EB177000F6EE86 /* AboutNetNewsWireView.swift */,
DFC14F1628EB17A800F6EE86 /* CreditsNetNewsWireView.swift */,
DFC14F1628EB17A800F6EE86 /* AboutNewNewsWireView.swift */,
DF5124CB2A22D62600BBAB1F /* AboutHTML.swift */,
);
path = About;
sourceTree = "<group>";
@@ -4485,7 +4482,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 */,
@@ -4493,7 +4489,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 */,