mirror of
https://github.com/Ranchero-Software/NetNewsWire
synced 2025-08-12 06:26:36 +00:00
Merge pull request #4676 from stuartbreckenridge/experimental/liquid-glass
Modernised About Panel
This commit is contained in:
80
Mac/About/AboutWindowController.swift
Normal file
80
Mac/About/AboutWindowController.swift
Normal file
@@ -0,0 +1,80 @@
|
||||
//
|
||||
// AboutWindowController.swift
|
||||
// NetNewsWire
|
||||
//
|
||||
// Created by Stuart Breckenridge on 26/06/2025.
|
||||
// Copyright © 2025 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
|
||||
class AboutWindowController: NSWindowController {
|
||||
|
||||
@IBOutlet weak var appIconImageView: NSImageView!
|
||||
@IBOutlet weak var appTitleLabel: NSTextField!
|
||||
@IBOutlet weak var versionLabel: NSTextField!
|
||||
@IBOutlet weak var copyrightLabel: NSTextField!
|
||||
@IBOutlet weak var websiteLabel: LinkLabel!
|
||||
@IBOutlet weak var creditsTextView: NSTextView!
|
||||
|
||||
override func windowDidLoad() {
|
||||
super.windowDidLoad()
|
||||
configureWindow()
|
||||
updateUI()
|
||||
}
|
||||
|
||||
func configureWindow() {
|
||||
window?.isOpaque = false
|
||||
window?.backgroundColor = .clear
|
||||
window?.titlebarAppearsTransparent = true
|
||||
window?.titleVisibility = .hidden
|
||||
window?.styleMask.insert(.fullSizeContentView)
|
||||
if let contentView = window?.contentView {
|
||||
let visualEffectView = NSVisualEffectView(frame: contentView.bounds)
|
||||
visualEffectView.autoresizingMask = [.width, .height]
|
||||
visualEffectView.blendingMode = .behindWindow
|
||||
visualEffectView.material = .titlebar
|
||||
visualEffectView.state = .active
|
||||
contentView.addSubview(visualEffectView, positioned: .below, relativeTo: nil)
|
||||
}
|
||||
}
|
||||
|
||||
private func updateUI() {
|
||||
|
||||
// App Icon
|
||||
appIconImageView.image = NSApp.applicationIconImage
|
||||
|
||||
// Version
|
||||
let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "Unknown"
|
||||
let build = Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? "Unknown"
|
||||
let versionString = "Version \(version) (Build \(build))"
|
||||
versionLabel.stringValue = versionString
|
||||
|
||||
// Copyright
|
||||
let copyright = Bundle.main.infoDictionary?["NSHumanReadableCopyright"] as? String ?? "Copyright © 2002-2025 Brent Simmons. All rights reserved."
|
||||
copyrightLabel.stringValue = copyright
|
||||
|
||||
// Credits
|
||||
if let creditsURL = Bundle.main.url(forResource: "Credits", withExtension: "rtf"),
|
||||
let creditsData = try? Data(contentsOf: creditsURL),
|
||||
let attributedString = try? NSAttributedString(data: creditsData, options: [.documentType: NSAttributedString.DocumentType.rtf], documentAttributes: nil) {
|
||||
creditsTextView.textStorage?.setAttributedString(attributedString)
|
||||
} else {
|
||||
creditsTextView.string = "Credits not available."
|
||||
}
|
||||
|
||||
let fullRange = NSRange(location: 0, length: creditsTextView.string.utf16.count)
|
||||
let leadingParagraphStyle = NSMutableParagraphStyle()
|
||||
leadingParagraphStyle.alignment = .left
|
||||
creditsTextView.textStorage?.addAttribute(.paragraphStyle, value: leadingParagraphStyle, range: fullRange)
|
||||
|
||||
// URL
|
||||
let url = URL(string: "https://inessential.com")!
|
||||
let attributedString = NSMutableAttributedString(string: "inessential.com")
|
||||
attributedString.addAttribute(.link, value: url, range: NSRange(location: 0, length: attributedString.length))
|
||||
attributedString.addAttribute(.foregroundColor, value: NSColor.systemBlue, range: NSRange(location: 0, length: attributedString.length))
|
||||
attributedString.addAttribute(.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: NSRange(location: 0, length: attributedString.length))
|
||||
websiteLabel.attributedStringValue = attributedString
|
||||
}
|
||||
|
||||
}
|
||||
116
Mac/About/AboutWindowController.xib
Normal file
116
Mac/About/AboutWindowController.xib
Normal file
@@ -0,0 +1,116 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="24093.8" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24093.8"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="AboutWindowController" customModule="NetNewsWire" customModuleProvider="target">
|
||||
<connections>
|
||||
<outlet property="appIconImageView" destination="kFw-rc-wEJ" id="Cgj-qd-V1E"/>
|
||||
<outlet property="appTitleLabel" destination="zSW-nT-ANt" id="lFq-Kv-hqz"/>
|
||||
<outlet property="copyrightLabel" destination="aNw-sB-24m" id="dBq-XD-2fE"/>
|
||||
<outlet property="creditsTextView" destination="hXV-nv-VJf" id="Glp-al-KJm"/>
|
||||
<outlet property="versionLabel" destination="xLI-yT-116" id="bSA-Ip-EIj"/>
|
||||
<outlet property="websiteLabel" destination="quK-3X-Mnw" id="796-rs-sUS"/>
|
||||
<outlet property="window" destination="F0z-JX-Cv5" id="gIp-Ho-8D9"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<window title="Window" separatorStyle="none" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" titlebarAppearsTransparent="YES" titleVisibility="hidden" id="F0z-JX-Cv5">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES"/>
|
||||
<rect key="contentRect" x="196" y="120" width="490" height="274"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1728" height="1083"/>
|
||||
<view key="contentView" id="se5-gp-TjO">
|
||||
<rect key="frame" x="0.0" y="0.0" width="490" height="274"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="kFw-rc-wEJ">
|
||||
<rect key="frame" x="66" y="141" width="85" height="85"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="85" id="36U-FK-YAn"/>
|
||||
<constraint firstAttribute="width" constant="85" id="GX8-xO-f4C"/>
|
||||
</constraints>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" image="icon" id="G5J-V9-bZN"/>
|
||||
</imageView>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="zSW-nT-ANt">
|
||||
<rect key="frame" x="56" y="114" width="105" height="19"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" title="NetNewsWire" id="gJ9-0j-Zg6">
|
||||
<font key="font" size="16" name="SFProDisplay-Semibold"/>
|
||||
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="aNw-sB-24m">
|
||||
<rect key="frame" x="18" y="56" width="181" height="28"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" alignment="center" title="© 2002 - 2025 Brent Simmons. All rights reserved." id="1hS-Cw-3kX">
|
||||
<font key="font" textStyle="subheadline" name=".SFNS-Regular"/>
|
||||
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<scrollView fixedFrame="YES" borderType="none" horizontalLineScroll="10" horizontalPageScroll="10" verticalLineScroll="10" verticalPageScroll="10" hasHorizontalScroller="NO" translatesAutoresizingMaskIntoConstraints="NO" id="HQS-xi-g6z">
|
||||
<rect key="frame" x="215" y="28" width="255" height="198"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<clipView key="contentView" drawsBackground="NO" id="aNl-9n-tcX">
|
||||
<rect key="frame" x="0.0" y="0.0" width="255" height="198"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textView wantsLayer="YES" editable="NO" drawsBackground="NO" importsGraphics="NO" verticallyResizable="YES" allowsCharacterPickerTouchBarItem="NO" textCompletion="NO" spellingCorrection="YES" smartInsertDelete="YES" id="hXV-nv-VJf">
|
||||
<rect key="frame" x="0.0" y="0.0" width="255" height="198"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<size key="minSize" width="255" height="198"/>
|
||||
<size key="maxSize" width="265" height="10000000"/>
|
||||
</textView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</clipView>
|
||||
<scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="ZAE-ok-OL5">
|
||||
<rect key="frame" x="-100" y="-100" width="240" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
<scroller key="verticalScroller" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="y4e-dI-wGV">
|
||||
<rect key="frame" x="238" y="0.0" width="17" height="198"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</scroller>
|
||||
</scrollView>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" contentType="url" translatesAutoresizingMaskIntoConstraints="NO" id="quK-3X-Mnw" customClass="LinkLabel" customModule="NetNewsWire" customModuleProvider="target">
|
||||
<rect key="frame" x="64" y="34" width="90" height="14"/>
|
||||
<textFieldCell key="cell" alignment="center" title="inessential.com" id="TYf-Hx-QuA">
|
||||
<font key="font" textStyle="subheadline" name=".SFNS-Regular"/>
|
||||
<color key="textColor" name="linkColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="xLI-yT-116">
|
||||
<rect key="frame" x="18" y="92" width="181" height="14"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" title="Version Text" id="G9F-XS-Hb5">
|
||||
<font key="font" textStyle="subheadline" name=".SFNS-Regular"/>
|
||||
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="quK-3X-Mnw" secondAttribute="bottom" constant="34" id="0Vv-qV-Blm"/>
|
||||
<constraint firstItem="kFw-rc-wEJ" firstAttribute="leading" secondItem="se5-gp-TjO" secondAttribute="leading" constant="66" id="4zV-p0-XWQ"/>
|
||||
<constraint firstItem="kFw-rc-wEJ" firstAttribute="top" secondItem="se5-gp-TjO" secondAttribute="top" constant="48" id="dvK-Oy-KgA"/>
|
||||
<constraint firstItem="quK-3X-Mnw" firstAttribute="centerX" secondItem="kFw-rc-wEJ" secondAttribute="centerX" id="zuU-IM-WmK"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="-2" id="0bl-1N-AYu"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="144" y="132"/>
|
||||
</window>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="icon" width="128" height="128"/>
|
||||
</resources>
|
||||
</document>
|
||||
16
Mac/About/LinkLabel.swift
Normal file
16
Mac/About/LinkLabel.swift
Normal file
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// LinkLabel.swift
|
||||
// NetNewsWire
|
||||
//
|
||||
// Created by Stuart Breckenridge on 26/06/2025.
|
||||
// Copyright © 2025 Ranchero Software. All rights reserved.
|
||||
//
|
||||
|
||||
|
||||
class LinkLabel: NSTextField {
|
||||
|
||||
/// pièces de résistance -- keeping it a mac-assed mac app.
|
||||
override func resetCursorRects() {
|
||||
addCursorRect(bounds, cursor: .pointingHand)
|
||||
}
|
||||
}
|
||||
@@ -277,7 +277,6 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
|
||||
CrashReporter.check(crashReporter: self.crashReporter)
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
func application(_ application: NSApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([NSUserActivityRestoring]) -> Void) -> Bool {
|
||||
@@ -675,6 +674,13 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSUserInterfaceValidations,
|
||||
createAndShowMainWindowIfNecessary()
|
||||
mainWindowController!.gotoStarred(sender)
|
||||
}
|
||||
|
||||
@IBAction func showCustomAboutPanel(_ sender: Any?) {
|
||||
let aboutWC = AboutWindowController(windowNibName: "AboutWindowController")
|
||||
aboutWC.showWindow(nil)
|
||||
aboutWC.window?.center()
|
||||
aboutWC.window?.makeKeyAndOrderFront(nil)
|
||||
}
|
||||
|
||||
@IBAction func sortByOldestArticleOnTop(_ sender: Any?) {
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="23504" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="24093.8" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="23504"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="24093.8"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Application-->
|
||||
@@ -18,7 +17,7 @@
|
||||
<menuItem title="About NetNewsWire" id="5kV-Vb-QxS">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="orderFrontStandardAboutPanel:" target="Ady-hI-5gd" id="Exp-CZ-Vem"/>
|
||||
<action selector="showCustomAboutPanel:" target="Voe-Tx-rLC" id="ZQV-QH-KmS"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
|
||||
|
||||
@@ -1,52 +1,64 @@
|
||||
{\rtf1\ansi\ansicpg1252\cocoartf2761
|
||||
\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset0 LucidaGrande-Bold;\f1\fnil\fcharset0 LucidaGrande;}
|
||||
{\rtf1\ansi\ansicpg1252\cocoartf2859
|
||||
\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fnil\fcharset0 SFPro-Bold;\f1\fnil\fcharset0 SFPro-Regular;}
|
||||
{\colortbl;\red255\green255\blue255;\red0\green0\blue0;}
|
||||
{\*\expandedcolortbl;;\cssrgb\c0\c0\c0\cname textColor;}
|
||||
\vieww14060\viewh15660\viewkind0
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\sl360\slmult1\pardirnatural\partightenfactor0
|
||||
{\field{\*\fldinst{HYPERLINK "https://ranchero.com/netnewswire/"}}{\fldrslt
|
||||
\f0\b\fs22 \cf2 NetNewsWire}}
|
||||
\f0\b\fs22 \cf2 \
|
||||
By Brent Simmons\
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\sl360\slmult1\pardirnatural\partightenfactor0
|
||||
{\field{\*\fldinst{HYPERLINK "http://inessential.com/"}}{\fldrslt \cf2 inessential.com}}
|
||||
\deftab720
|
||||
\pard\pardeftab720\sa60\partightenfactor0
|
||||
|
||||
\f0\b\fs22 \cf2 Credits
|
||||
\f1\b0 \
|
||||
\pard\pardeftab720\sl144\slmult1\sa60\partightenfactor0
|
||||
\cf2 \
|
||||
\pard\pardeftab720\sl168\slmult1\sa60\partightenfactor0
|
||||
\cf2 Contributing Developers \
|
||||
{\field{\*\fldinst{HYPERLINK "https://github.com/vincode-io"}}{\fldrslt Maurice Parker}}, {\field{\*\fldinst{HYPERLINK "https://stuartbreckenridge.net/"}}{\fldrslt Stuart Breckenridge}}\
|
||||
\
|
||||
App Icon\
|
||||
{\field{\*\fldinst{HYPERLINK "https://twitter.com/BradEllis"}}{\fldrslt Brad Ellis}}\
|
||||
\
|
||||
Feedly Syncing\
|
||||
{\field{\*\fldinst{HYPERLINK "https://twitter.com/kielgillard"}}{\fldrslt Kiel Gillard}}\
|
||||
\
|
||||
NewsBlur Syncing\
|
||||
{\field{\*\fldinst{HYPERLINK "https://twitter.com/quanganhdo"}}{\fldrslt Anh Do}}\
|
||||
\
|
||||
Under-the-Hood Magic and CSS Stylin's\
|
||||
{\field{\*\fldinst{HYPERLINK "https://github.com/wevah"}}{\fldrslt Nate Weaver}}\
|
||||
\
|
||||
Newsfoot (JS footnote displayer)\
|
||||
{\field{\*\fldinst{HYPERLINK "https://github.com/brehaut/"}}{\fldrslt Andrew Brehaut}}\
|
||||
\
|
||||
Help Book\
|
||||
{\field{\*\fldinst{HYPERLINK "https://nostodnayr.net/"}}{\fldrslt Ryan Dotson}}\
|
||||
\
|
||||
And featuring contributions from\
|
||||
{\field{\*\fldinst{HYPERLINK "https://github.com/danielpunkass"}}{\fldrslt Daniel Jalkut}}, {\field{\*\fldinst{HYPERLINK "https://rhonabwy.com/"}}{\fldrslt Joe Heck}}, {\field{\*\fldinst{HYPERLINK "https://github.com/olofhellman"}}{\fldrslt Olof Hellman}}, {\field{\*\fldinst{HYPERLINK "https://blog.rizwan.dev/"}}{\fldrslt Rizwan Mohamed Ibrahim}}, {\field{\*\fldinst{HYPERLINK "https://twitter.com/philviso"}}{\fldrslt Phil Viso}}, and {\field{\*\fldinst{HYPERLINK "https://github.com/Ranchero-Software/NetNewsWire/graphs/contributors"}}{\fldrslt many more}}!\
|
||||
\pard\pardeftab720\li360\sa60\partightenfactor0
|
||||
\cf2 \
|
||||
\pard\pardeftab720\sa60\partightenfactor0
|
||||
|
||||
\f0\b \cf2 Credits:
|
||||
\f1\b0 \
|
||||
\pard\pardeftab720\li360\sa60\partightenfactor0
|
||||
\cf2 Contributing developers: {\field{\*\fldinst{HYPERLINK "https://github.com/vincode-io"}}{\fldrslt Maurice Parker}}, {\field{\*\fldinst{HYPERLINK "https://stuartbreckenridge.net/"}}{\fldrslt Stuart Breckenridge}}\
|
||||
App icon: {\field{\*\fldinst{HYPERLINK "https://twitter.com/BradEllis"}}{\fldrslt Brad Ellis}}\
|
||||
Feedly syncing: {\field{\*\fldinst{HYPERLINK "https://twitter.com/kielgillard"}}{\fldrslt Kiel Gillard}}\
|
||||
NewsBlur syncing: {\field{\*\fldinst{HYPERLINK "https://twitter.com/quanganhdo"}}{\fldrslt Anh Do}}\
|
||||
Under-the-hood magic and CSS stylin\'92s: {\field{\*\fldinst{HYPERLINK "https://github.com/wevah"}}{\fldrslt Nate Weaver}}\
|
||||
Newsfoot (JS footnote displayer): {\field{\*\fldinst{HYPERLINK "https://github.com/brehaut/"}}{\fldrslt Andrew Brehaut}}\
|
||||
Help book: {\field{\*\fldinst{HYPERLINK "https://nostodnayr.net/"}}{\fldrslt Ryan Dotson}}\
|
||||
And featuring contributions from {\field{\*\fldinst{HYPERLINK "https://github.com/danielpunkass"}}{\fldrslt Daniel Jalkut}}, {\field{\*\fldinst{HYPERLINK "https://rhonabwy.com/"}}{\fldrslt Joe Heck}}, {\field{\*\fldinst{HYPERLINK "https://github.com/olofhellman"}}{\fldrslt Olof Hellman}}, {\field{\*\fldinst{HYPERLINK "https://blog.rizwan.dev/"}}{\fldrslt Rizwan Mohamed Ibrahim}}, {\field{\*\fldinst{HYPERLINK "https://twitter.com/philviso"}}{\fldrslt Phil Viso}}, and {\field{\*\fldinst{HYPERLINK "https://github.com/Ranchero-Software/NetNewsWire/graphs/contributors"}}{\fldrslt many more}}!\
|
||||
\
|
||||
\pard\pardeftab720\sa60\partightenfactor0
|
||||
\f0\b \cf2 Acknowledgments\
|
||||
|
||||
\f0\b \cf2 Acknowledgments:
|
||||
\f1\b0 \
|
||||
\pard\pardeftab720\li360\sa60\partightenfactor0
|
||||
\pard\pardeftab720\sl168\slmult1\sa60\partightenfactor0
|
||||
{\field{\*\fldinst{HYPERLINK "https://github.com/ccgus/fmdb"}}{\fldrslt \cf2 FMDB}} (greatest SQLite wrapper ever in history) is by {\field{\*\fldinst{HYPERLINK "http://flyingmeat.com/"}}{\fldrslt Flying Meat Software}}.\
|
||||
\pard\pardeftab720\li360\sa60\partightenfactor0
|
||||
{\field{\*\fldinst{HYPERLINK "https://sparkle-project.org/"}}{\fldrslt \cf2 Sparkle}} is by Sparkle Project.\
|
||||
\
|
||||
{\field{\*\fldinst{HYPERLINK "https://sparkle-project.org/"}}{\fldrslt Sparkle}} is by Sparkle Project.\
|
||||
\pard\pardeftab720\li360\sa60\partightenfactor0
|
||||
\cf2 \
|
||||
\pard\pardeftab720\sa60\partightenfactor0
|
||||
|
||||
\f0\b \cf2 Thanks:\
|
||||
\pard\pardeftab720\li360\sa60\partightenfactor0
|
||||
|
||||
\f1\b0 \cf2 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 {\field{\*\fldinst{HYPERLINK "https://github.com/"}}{\fldrslt GitHub}} and {\field{\*\fldinst{HYPERLINK "https://slack.com/"}}{\fldrslt Slack}} for making open source collaboration easy and fun.\
|
||||
\f0\b \cf2 Thanks\
|
||||
\
|
||||
|
||||
\f1\b0 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 {\field{\*\fldinst{HYPERLINK "https://github.com/"}}{\fldrslt GitHub}} and {\field{\*\fldinst{HYPERLINK "https://slack.com/"}}{\fldrslt Slack}} for making open source collaboration easy and fun.\
|
||||
\pard\pardeftab720\li360\sa60\partightenfactor0
|
||||
\cf2 \
|
||||
\pard\pardeftab720\sa60\partightenfactor0
|
||||
|
||||
\f0\b \cf2 Dedication:\
|
||||
\pard\pardeftab720\li360\sa60\partightenfactor0
|
||||
\f0\b \cf2 Dedication\
|
||||
\
|
||||
|
||||
\f1\b0 \cf2 NetNewsWire 6 is dedicated to everyone working to save democracy around the world.\
|
||||
\f1\b0 NetNewsWire 6 is dedicated to everyone working to save democracy around the world.\
|
||||
}
|
||||
Reference in New Issue
Block a user